我有一个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不匹配。如何正确编写正则表达式?
答案 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 换行符。