如何在 Windows PowerShell 中捕获正则表达式匹配周围的特定行?

How to capture a specific line around a regex match in Windows PowerShell?

所以,这里是下面的例子。

Application Details for the XYZ application:
    =========================================================

    Application Name:       XYXZW1
    Application Id:         XYZ353WERX

Application Details for the XYZ application:
    =========================================================

    Application Name:       XYXZW2
    Application Id:         XYZ353WERX

Application Details for the XYZ application:
    =========================================================
 
    Application Name:       XYXZW3
    Application Id:         XYZ353WERX
    Secret Key:             XYZ86JBHHSD

Application Details for the XYZ application:
    =========================================================

    Application Name:       XYXZW4
    Application Id:         XYZ353WERX
    Secret Key:             XYZ86JBHHSD

现在我希望正则表达式仅匹配 windows powershell 中包含“密钥:值”对的那些“应用程序名称:值”。 我不确定这可能是正则表达式参考,它不适用于 windows powerShell。

$input_path = ‘C:\Users\Steve\Downloads\input.txt’
$regex = '\s*Application Name:\s*.*\r?\n\s*(?=Application Id \(ClientId\):\s*.*\r?\n\s*Secret Key:\s*.*)|\s*Secret Key:\s*.*'
select-string -Path $input_path -Pattern $regex -AllMatches |  Write-Output

所有类型的正则表达式在不同平台上都能很好地工作(尝试了几个)但在 Windows powerShell 上却不行。

输出应如下所示:

   Application Name: XYXZW3 
   Secret Key: XYZ86JBHHSD 
   Application Name: XYXZW4 
   Secret Key: XYZ86JBHHSD 

要做到这一点,您需要使用 look-arounds

/(?<=Application Name:)[^\n]*(?=[^=]*(?=Secret Key))/g

如果 Secret Key 出现在 = 字符之前,它会捕获 Application Name:\n 之间的所有内容。

它也捕获所有 space 个字符。如果你不想要它并且你知道确切的空格数,那么你可以将它更改为

/(?<=Application Name:\s{7})[^\n]*(?=[^=]*(?=Secret Key))/g

7是要跳过的空格数。

Demo.

更新:

同时捕获 Secret 值更改为

/(?<=Application Name:\s{7})[^\n]*(?=[^=]*(?=Secret Key))/g

您需要将两个连续匹配项处理为一对 Application NameSecret Key

Demo.

如果要获取应用程序名称和密钥的值,可以使用 2 个捕获组

^[\p{Zs}\t]*Application Name:[\p{Zs}\t]*(.+)\r?\n[\p{Zs}\t]*Application Id:.*\r?\n[\p{Zs}\t]*Secret Key:[\p{Zs}\t]*(.+)

模式匹配:

  • ^ 字符串开头
  • [\p{Zs}\t]* 匹配可选的水平空白字符
  • Application Name:[\p{Zs}\t]* 匹配应用程序名称:和可选空格
  • (.+) 捕获 group 1,Application Name
  • 的值
  • \r?\n[\p{Zs}\t]* 匹配换行符和可选空格
  • Application Id:.*\r?\n 匹配 Applicatino Id: 和行的其余部分
  • [\p{Zs}\t]*Secret Key:[\p{Zs}\t]*匹配密钥:可选空格之间
  • (.+) 捕获 组 2,Secret Key 的值

Regex demo


如果您只想匹配存在密钥的应用程序名称的值,您还可以使用环视来断言左侧的 Application Name: 和左侧的 Secret Key:没有越过至少以 ==

开头的线
(?<=^\s*Application Name:\s*)\S.*(?=(?:\r?\n(?!\s*==).*)*\r?\n\s*Secret Key:)

.NET regex demo

我会在这里依赖捕获组:

(?m)\bApplication Name:\s*(.+)(?:\n(?!\s*={3,}\r?$).*)*^\s*Secret Key:\s*(.+)
/\bApplication Name:\s*(.+)(?:\n(?!\s*={3,}\r?$).*)*^\s*Secret Key:\s*(.+)/gm

参见regex demo详情:

  • \bApplication Name: - 一个完整的单词 Application, space, Name, :`
  • \s* - 零个或多个白色spaces
  • (.+) - 第 1 组:一个或多个除换行字符外的字符尽可能多
  • (?:\n(?!\s*={3,}\r?$).*)* - 不以零个或多个白色 space 开头的任意数量的行,后跟三个或更多 = 个字符,直到行尾(\r? 仅在您必须处理正则表达式时才在此处添加,其中 $/m 标志在 CR 字符之前不匹配,如在 .NET 中)
  • ^ - 行首
  • \s* - 一个或多个白色spaces
  • Secret Key: - Secret Key: 字符串
  • \s* - 零个或多个白色spaces
  • (.+) - 第 2 组:一个或多个除换行字符外的字符尽可能多