【问题标题】:Trying to match this using regular expressions in PowerShell尝试在 PowerShell 中使用正则表达式进行匹配
【发布时间】:2015-07-12 05:17:30
【问题描述】:

我正在尝试使用正则表达式来匹配文件中的某些行,但遇到了一些问题。

该文件包含如下文本:

Mario, 123456789
Luigi, 234-567-890
Nancy, 345 5666 77533
Bowser, 348759823745908732589
Peach, 534785
Daisy, 123-456-7890

我正在尝试将数字匹配为 XXX-XXX-XXX 或 XXX XXX XXX 模式。

我尝试了几种不同的方法,但它总是期待一些我不想要的东西,或者它告诉我一切都是错误的。

我正在使用 PowerShell 来执行此操作。

一开始我试过:

{$match = $i -match "\d{3}\-\d{3}\-\d{3}|\d{3}\ \d{3}\ \d{3}"
Write-Host $match}

但是当我这样做时,它会匹配长强的数字和XXX-XXX-XXXXX

我读到一些东西说 n 会匹配确切的数量,所以我尝试了一下......

{$match = $i -match "\d{n3}\-\d{n3}\-\d{n3}|\d{n3}\ \d{n3}\ \{n3}"
Write-Host $match}

这让一切都是假的......

所以我尝试了

{$match = $i -match "\d\n{3}\-\d\n{3}\-\d\n{3}|\d\n{3}\ \d\n{3}\ \d\n{3}"

我也尝试了惰性量词?

{$match = $i -match "\d{3?}\-\d{3?}\-\d{3?}|\d{3?}\ \{3?}\ \{3?}"
Write-Host $match}

还是假的……

我尝试的最后一件事是这个......

{$match = $i -match "\d[0-9\{3\}\-\d[0-9]\{3\}\-\d[0-9]{3\}|\d[0-9]\{3\}\ \d[0-9]\{3}\ \d[0-9]\{3\}"<br>
Write-Host $match}

仍然没有运气......

【问题讨论】:

    标签: regex powershell


    【解决方案1】:

    以下模式给出了两个匹配项:

    Get-Content .\test.txt | Where-Object {$_ -match '\d{3}[-|\s]\d{3}[-|\s]\d{3}'}
    

    路易吉,234-567-890
    雏菊, 123-456-7890

    如果要排除最后一个匹配,添加'$'锚点(代表字符串的结尾:

    Get-Content .\test.txt | Where-Object {$_ -match '\d{3}[-|\s]\d{3}[-|\s]\d{3}$'}
    

    路易吉,234-567-890

    如果您想非常具体并从头到尾匹配行(使用 ^ 锚点,表示字符串的开头):

    Get-Content .\test.txt | Where-Object {$_ -match '^\w+,\s+\d{3}[-|\s]\d{3}[-|\s]\d{3}$'}
    

    路易吉,234-567-890

    【讨论】:

      【解决方案2】:

      您的第一个答案是最接近的。 {3} 正好匹配 3 个字符。我认为您看到的 n 应该代表任何数字,而不是实际的 n 字符。它匹配长字符串的原因是您只指定匹配必须找到 3 个数字、破折号或空格、3 个数字、破折号或空格,然后再找到 3 个数字。您没有指定如果之后有更多数字则不计算在内。

      如果后面有数字时不匹配,可以使用negative lookahead

      (\d{3}-\d{3}-\d{3}|\d{3}\ \d{3}\ \d{3})(?!\d)
      

      或者,如果您只想匹配行尾,可能带有尾随空格

      (\d{3}-\d{3}-\d{3}|\d{3}\ \d{3}\ \d{3})\s*$
      

      【讨论】:

      • 非常感谢您的帮助。
      【解决方案3】:

      正如 Gideon 所说,您的第一个是最好的起点。

      "\b\d{3}\-\d{3}\-\d{3}\b|\b\d{3}\ \d{3}\ \d{3}\b"
      

      在每个语句之前和之后添加的\b 特殊字符是单词边界 - 基本上是空格或换行符或标点符号,如句号或逗号。这确保9999 不匹配,但999. 匹配。

      【讨论】:

        【解决方案4】:

        试试这个:

        /(\d+[- ])+\d+/
        

        最好不要有这么严格的正则表达式,除非你绝对确定你的输入不会改变。

        所以这个正则表达式至少匹配一个数字,然后贪婪地搜索更多数字,后跟空格或破折号。这也尽可能多地重复,然后至少跟着另一个数字。

        【讨论】:

          【解决方案5】:

          在 PowerShell 中操作数据时,创建表示数据的对象通常是一个好主意(毕竟,PowerShell 是关于对象的)。基于对象属性的过滤通常更容易且更健壮。你的问题就是一个很好的例子。 这是我们所追求的:

          • 人员:$persons
          • 地点:地点
          • 那个人的号码:$_.number
          • 匹配:-匹配
          • 模式
          • 以三位数开头:^\d{3}
          • 后跟三位数之间的破折号或空格:(-\d{3}-|\ \d{3}\ )
          • 以三位数结尾:\d{3}$

          以下是整个脚本:

          $persons = import-csv -Header "name", "number" -delimiter "," data.csv
          $persons | where {$_.number -match "^\d{3}(\-\d{3}\-|\ \d{3}\ )\d{3}$"}
          

          【讨论】:

            【解决方案6】:

            你也可以使用Select-String:

            Select-String '(\d{3}[ -]){2}\d{3}$' .\file.txt | % {$_.Line}
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-01-22
              • 1970-01-01
              • 1970-01-01
              • 2011-08-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-04-10
              相关资源
              最近更新 更多