【问题标题】:PowerShell regex does not match near newlinePowerShell 正则表达式在换行符附近不匹配
【发布时间】:2019-03-09 18:11:50
【问题描述】:

我在表单中有一个 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 不匹配。如何正确编写正则表达式?

【问题讨论】:

  • 我怀疑你最后可能有\r\n。但是,您根本不需要前瞻,因为要到达第一个换行符,您可以使用 .*.+
  • @PetSerAl 奇怪,tio.run 工作正常,但我的本地脚本没有?神秘?
  • @PetSerAl 比你们所有人。我明白了,我将 exe 输出转换为字符串 (| Out-String) 并且它获得了。

标签: regex powershell newline


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

    您关于通过管道连接到Out-String 来解决您的问题的后续评论暗示您的问题是$exeOutput 包含一个数组 行而不是一个单行、多行 字符串。

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

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

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

    或者,考虑到 $exeOutput 中行的特定格式,您可以利用
    ConvertFrom-StringData cmdlet,它可以在替换 : 分隔符后为您将行解析为键值对=:

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

    [1] 使用 cmdlet 通常比使用 表达式 慢;使用字符串数组$array 作为输入,您可以使用$array -join "`n" 更有效地实现$array | Out-String 所做的事情,但请注意Out-String 还附加了一个尾随 换行符。

    【讨论】:

      猜你喜欢
      • 2021-12-14
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-05
      相关资源
      最近更新 更多