PowerShell正则表达式在换行符附近不匹配

时间:2019-03-09 18:11:51

标签: regex powershell newline

我有一个exe输出格式

Compression          : CCITT Group 4
Width                : 3180

并尝试使用PowerShell脚本将CCITT Group 4提取到$var

$var = [regex]::match($exeoutput,'Compression\s+:\s+([\w\s]+)(?=\n)').Groups[1].Value

http://regexstorm.net/tester说,正则表达式Compression\s+:\s+([\w\s]+)(?=\n)是正确的,但不是PowerShell。 PowerShell不匹配。如何正确编写正则表达式?

2 个答案:

答案 0 :(得分:2)

您要从某个特定模式获取所有文本,直到该行的末尾。因此,您甚至不需要先行(?=\n),只需使用.+,因为.匹配任何字符,但匹配换行符(LF)的字符:

$var = [regex]::match($exeoutput,'Compression\s+:\s+(.+)').Groups[1].Value

或者,您可以使用-match运算符,并在找到匹配项后使用$matches[1]访问捕获的值:

$exeoutput -match 'Compression\s*:\s*(.+)'
$var = $matches[1]

答案 1 :(得分:1)

Wiktor Stribiżew's helpful answer简化了正则表达式,并向您展示了如何使用PowerShell的
-match运算符作为替代。

您关于通过管道Out-String解决问题的后续评论表示您的问题是$exeOutput包含行的数组而不是单行,多行字符串。

当您捕获来自对外部程序的调用(*.exe)的输出时,确实发生了这种情况:PowerShell将stdout输出行捕获为字符串数组 < / strong>(没有尾随换行符的行)。

作为将数组$exeOutput转换为带有Out-String的单个多行字符串(顺便说一句,它很慢 [1] )的替代方法,您可以使用{ {3}}直接在数组上操作:

# Stores 'CCITT Group 4' in $var
$var = switch -regex ($exeOutput) { 'Compression\s+:\s+(.+)' { $Matches[1]; break } }

或者,给定$exeOutput中行的特定格式,您可以利用
switch statement,该行可以在替换后将行解析为键值对:=分隔符:

$var = ($exeoutput -replace ':', '=' | ConvertFrom-StringData).Compression

[1]使用 cmdlet 通常比使用 expression 慢。使用字符串数组$array作为输入,您可以使用$array | Out-String来更有效地实现$array -join "`n"的功能,但是请注意Out-String还会附加一个 trailing 换行符。