【问题标题】:Using regex within text with carriage return在带有回车的文本中使用正则表达式
【发布时间】:2021-10-03 17:55:18
【问题描述】:

我正在使用 powershell 在 txt 中使用正则表达式,但它仅在文本不包含回车时才有效。我准备了一个这样的示例文件:

the duck is on the table --found!  

the elephant is on  the table --found! 

the cat is  
on the table --NOT found!  :-(

the lion is on the tablet --NOT found but ok ;-)

the dog is on  
the table               --NOT found!  :-(

the turtle isonthe table --NOT found but ok ;-)

the cow is on the              table --found! 

我想要包含“在桌子上”的案例,所以我执行了这个:

select-string -path "c:\example.txt" -pattern '([^\w]{1})on([^\w])+the([^\w])+table([^\w]{1})'

这是输出:


example.txt:1:鸭子在桌子上——找到了!

example.txt:2:大象在桌子上——找到了!

example.txt:14:牛在桌子上——找到了!


但我也需要回车的情况!猫在哪里?狗在哪里?

谢谢你;-)

【问题讨论】:

  • 在测试匹配之前尝试从字符串中删除任何回车/换行符。

标签: regex powershell select-string


【解决方案1】:

通过Select-String-Path-LiteralPath 参数提供文件输入,逐行处理目标文件,如也在Santiago Squarzon's helpful answer中指出。

为了匹配模式跨行,文件的内容必须作为单行多行字符串传递,这就是Get-Content' s -Raw 开关可以

此外,为了报告该多行字符串内的多个匹配项,必须使用Select-String-AllMatches 开关

然后可以通过Microsoft.PowerShell.Commands.MatchInfo 实例的.Matches 属性处理结果匹配,Select-Object 输出:

Get-Content -Raw example.txt | 
  Select-String -AllMatches '(?m)^.*?\son\s+the\s+table\b.*$' |
    ForEach-Object {
      foreach ($match in $_.Matches) {
        "[$($match.Value)]"
      }
    }

有关上面使用的regex 的解释,请参阅this regex101.com page[1]

以上产量:

[the duck is on the table]
[the elephant is on  the table]
[the cat is  
on the table]
[the dog is on  
the table]
[the cow is on the              table]

[1] 请注意,尽管 regex101.com,一个用于可视化、解释和试验正则表达式的网站,不支持 PowerShell 使用的 .NET 正则表达式引擎,但选择一个类似的引擎,例如 Java 的引擎,通常表现出相同的行为,至少从根本上是这样。

【讨论】:

    【解决方案2】:

    我不确定这是否可以使用 Select-String,因为它逐行而不是作为单个多行读取文件 string 但这对我有用:

    $tmp = New-TemporaryFile
    
    @'
    the duck is on the table 
    
    the elephant is on the table 
    
    the cat is
    on the table
    
    the lion is on the tablet
    
    the dog is on
    the table
    
    the turtle isonthe table
    
    the cow is on the table 
    '@ | Set-Content $tmp
    
    
    $content = Get-Content $tmp -Raw
    [regex]::Matches($content, '.*[^\w]on[^\w]+the[^\w]+table[^\w].*') |
    Select-Object Index,Value | Format-Table -Wrap
    

    结果:

    Index Value                         
    ----- -----                         
        0 the duck is on the table      
       29 the elephant is on the table  
       62 the cat is                    
          on the table                  
      119 the dog is on                 
          the table                     
      175 the cow is on the table   
    

    如果您只想在单词之间使用空格可能会更好:

    '.*\son\s+the\s+table\s.*'
    

    如果你想不区分大小写:

    [regex]::Matches($content, '.*[^\w]on[^\w]+the[^\w]+table[^\w].*', [System.StringComparison]::OrdinalIgnoreCase)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多