【问题标题】:PowerShell Regular Expression match Y or ZPowerShell 正则表达式匹配 Y 或 Z
【发布时间】:2019-03-06 06:15:23
【问题描述】:

我正在尝试使用 PowerShell 中的正则表达式匹配一些字符串,但由于我从中提取的原始字符串的格式不同,遇到了困难。诚然,我不擅长创建正则表达式。

我需要从每个字符串中提取数字。它们的长度可能会有所不同,但在这两种情况下都将在前面加上Foo

PC1-FOO1234567
PC2-FOO1234567/FOO98765

这适用于第二个示例:

'PC2-FOO1234567/FOO98765' -match 'FOO(.*?)\/FOO(.*?)\z'

它让我可以使用$matches[1]$matches[2] 访问匹配的字符串,这很棒。

这显然不适用于第一个示例。我怀疑我需要一些方法来匹配/ 或字符串的结尾,但我不确定如何做到这一点并最终得到我想要的匹配。

建议?

【问题讨论】:

  • 使用'FOO(.*?)(?:/FOO(.*))?$'
  • 顺便说一句:只有在将/.../ 用于正则表达式文字的语言中,您需要将/ 转义为\/(PowerShell 不是其中之一)。

标签: regex powershell


【解决方案1】:

你可以使用

'FOO(.*?)(?:/FOO(.*))?$'

它将匹配FOO,然后尽可能少地将任何0个或多个字符捕获到第1组中,然后将尝试有选择地匹配一系列模式:/FOO,尽可能多地捕获任何0个或多个字符进入第 2 组,然后应该跟随字符串位置的结尾。

regex demo

详情

  • FOO - 文字子串
  • (.*?) - 第 1 组:除换行符以外的任何零个或多个字符,尽可能少
  • (?:/FOO(.*))? - 一个可选的非捕获组,匹配 1 次或 0 次重复:
    • /FOO - 文字子字符串
    • (.*) - 第 2 组:除换行符之外的任何 0+ 字符尽可能多(* 是贪婪的)
  • $ - 字符串结束。

【讨论】:

    【解决方案2】:

    [编辑 - 将不需要的管道删除到 Where-Object。感谢 mklement0 ! [*咧嘴*]]

    这是一种有些不同的方法。它在foo 上拆分,然后将不需要的/ 替换为空,最后过滤掉任何包含字母的字符串。

    其他人提供的纯正则表达式解决方案可能会更快,但这可能更容易理解——因此也更容易维护。 [咧嘴一笑]

    # fake reading in a text file
    #    in real life, use Get-Content
    $InStuff = @'
    PC1-FOO1234567
    PC2-FOO1234567/FOO98765
    '@ -split [environment]::NewLine
    
    $InStuff -split 'foo' -replace '/' -notmatch '[a-z]'
    

    输出...

    1234567
    1234567
    98765
    

    【讨论】:

      【解决方案3】:

      为了提供更简洁的-split 运算符的替代方案,这样就无需在之后访问$Matches 以提取数字:

      PS> 'PC1-FOO1234568', 'PC2-FOO1234567/FOO98765' -split '(?:^PC\d+-|/)FOO' -ne ''
      1234568  # single match from 1st input string
      1234567  # first of 2 matches from 2nd input string
      98765
      

      注意:-split 总是返回一个 [string[]] 数组,即使只返回 1 个字符串;来自多个输入字符串的结果字符串被组合成一个单一的平面数组。

      • ^PC\d+-|/ 匹配 PC 后跟 1 个或多个 (+) 数字 (\d) 在字符串开头 (^) (|)一个/ 字符,匹配开头的PC2-FOO/FOO

        • (?:...),一个非捕获子表达式,必须用于防止-split在结果数组中包含匹配的子表达式。
      • -ne '' 过滤掉由以分隔符开始的输入字符串产生的元素。


      要详细了解基于正则表达式的-split 运算符以及它在哪些方面比基于字符串文字的.NET String.Split() 方法更强大,请参阅this answer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-16
        • 2014-09-10
        • 2011-08-18
        • 2014-01-07
        • 1970-01-01
        • 2015-03-05
        相关资源
        最近更新 更多