Regex 如何在Powershell中提取正则表达式反向引用/匹配的值

Regex 如何在Powershell中提取正则表达式反向引用/匹配的值,regex,powershell,Regex,Powershell,我有一个包含数据行的文本文件。我可以使用以下powershell脚本提取我感兴趣的行: select-string -path *.txt -pattern "subject=([A-Z\.]+)," 一些示例数据如下: blah blah subject=THIS.IS.TEST.DATA, blah blah blah 我想要的是能够提取主题的实际内容(即“THIS.is.TEST.DATA”字符串)。我试过这个: select-string -path *.txt -pattern "

我有一个包含数据行的文本文件。我可以使用以下powershell脚本提取我感兴趣的行:

select-string -path *.txt -pattern "subject=([A-Z\.]+),"
一些示例数据如下:

blah blah subject=THIS.IS.TEST.DATA, blah blah blah
我想要的是能够提取主题的实际内容(即“THIS.is.TEST.DATA”字符串)。我试过这个:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0] }

但是“Matches”属性始终为空。我做错了什么?

我不知道为什么你的版本不起作用。它应该会起作用。这是一个更丑陋的版本

$p = "subject=([A-Z\.]+),"
select-string -path *.txt -pattern $p | % {$_ -match $p > $null; $matches[1]}
说明:

-match
是正则表达式匹配运算符:

>"foobar" -match "oo.ar"
True
$null
仅抑制写入输出的True。(尝试删除它。)有一个cmdlet执行相同的操作,我现在记不起它的名称


$matches
是一个神奇的变量,它保存最后一次
-match
操作的结果。

您键入的代码的问题是select string没有传递实际的正则表达式对象。相反,它传递另一个名为MatchInfo的类,该类没有实际的正则表达式匹配信息

如果您只想运行一次正则表达式,那么您就必须运行自己的函数,这并不太困难

function Select-Match() {
  param ($pattern = $(throw "Need a pattern"), 
         $filePath = $(throw "Need a file path") )
  foreach ( $cur in (gc $filePath)) { 
    if ( $cur -match $pattern ) { 
      write-output $matches[0];
    }
  }
}

gci *.txt | %{ Select-Match "subject=([A-Z\.]+)," $_.FullName }
另一种选择

gci *.txt | foreach { [regex]::match($_,'(?<=subject=)([^,]+)').value }

gci*.txt | foreach{[regex]::match($),(?从所有其他答案中学到很多东西后,我能够使用以下行获得我想要的东西:

gci *.txt | gc | %{ [regex]::matches($_, "subject=([A-Z\.]+),") } | %{ $_.Groups[1].Value }

这感觉很好,因为我每行只运行一次正则表达式,在命令提示符下输入它时,没有多行代码也很好。

另一个变体,匹配字符串中的7位数字

echo "123456789 hello test" | % {$_ -match "\d{7}" > $null; $matches[0]}

返回:1234567

在PowerShell V2 CTP3中,已实现Matches属性。因此,以下操作将起作用:

select-string -path *.txt -pattern "subject=([A-Z\.]+)," | %{ $_.Matches[0].Groups[1].Value }

Select String命令似乎返回一个MatchInfo变量,而不是一个“String”变量。 我花了几个小时在论坛和官方网站上发现了这一点,但运气不好。 我还在收集信息。 解决此问题的一种方法是显式声明一个字符串变量,以保存从您的示例中的Select字符串返回的结果:

[string]$foo=select string-path*.txt-pattern“subject=([A-Z.]+),”

$foo变量现在是一个字符串,而不是MatchInfo对象

希望这有帮助


ps5 powershell版本5字符串操作

有一种更简单的选择字符串的方法,可以更好地工作

在powershell中

  • $sample=“blah blah subject=THIS.IS.TEST.DATA,blah blah blah”
  • $sample-match“主题=([A-Z\.]+),”
  • $matches[1]
    将包含您要查找的子字符串

  • 这适用于Windows 10.0.16299版本

    谢谢,这是可行的,但是您能解释一下您在做什么吗?特别是“$\uMatch$p>$null”位。dangph想到的cmdlet是“Out null”。但是您也可以将整行内容强制转换为[void]:[void]($\uMatch$p)但是为什么MatchInfo.Matches属性不起作用?@dangph,我相信这是文档中的一个bug。你可以通过运行“gci a*.txt | gm”来验证这一点。生成的类型没有Matches属性。JaredPar,这对我不起作用,但我相信你是对的。试试这个:“gm-inputobject(新对象Microsoft.PowerShell.Commands.MatchInfo)”。我猜他们只是还没有实现Matches属性。毕竟,我希望一个名为“MatchInfo”的类实际上包含关于匹配的信息:)我刚刚签入CTP3,Matches属性是为v2实现的。很高兴你找到了解决方案。我刚签入v2,Matches属性从Select String开始工作。因此,将来这对你来说不会那么痛苦。:)这对我有效。还有一些事情正在发生,比如使用powershell 1或一些奇怪的编码,如utf8无bom或utf16le无bombom.是迄今为止最干净、最简单的解决方案。应为#1。