如何在Powershell中提取regex回引用/匹配的值

时间:2023-01-14 14:15:10

I have a text file containing lines of data. I can use the following powershell script to extract the lines I'm interested in:

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

select-string -path *.txt -pattern "subject=([A-Z\.]+),"

Some example data would be:

一些例子数据是:

blah blah subject=THIS.IS.TEST.DATA, blah blah blah

What I want is to be able to extract just the actual contents of the subject (i.e. the "THIS.IS.TEST.DATA" string). I tried this:

我想要的是能够提取出主题的实际内容(即“THIS.IS.TEST”)。字符串数据”)。我试着这样的:

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

But the "Matches" property is always null. What am I doing wrong?

但是“Matches”属性总是为null。我做错了什么?

8 个解决方案

#1


9  

I don't know why your version doesn't work. It should work. Here is an uglier version that works.

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

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

Edit. Explanation for dant:

编辑。次煤的解释:

-match is a regular expression matching operator:

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

>"foobar" -match "oo.ar"
True

The > $null just suppresses the True being written to the output. (Try removing it.) There is a cmdlet that does the same thing whose name I don't recall at the moment.

> $null只会抑制将True写入输出的情况。(试着删除。)有一个cmdlet做同样的事情,我一时想不起它的名字。

$matches is a magic variable that holds the result of the last -match operation.

$matches是一个神奇的变量,它保存上一次匹配操作的结果。

#2


4  

In PowerShell V2 CTP3, the Matches property is implemented. So the following will work:

在PowerShell V2 CTP3中,匹配属性被实现。因此,以下方法将有效:

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

#3


2  

The problem with the code you are typing is that select-string does not pass down the actual Regex object. Instead it passes a different class called MatchInfo which does not have the actual regex matches information.

您所键入的代码的问题是,selectstring不传递实际的Regex对象。相反,它通过一个名为MatchInfo的不同的类,它没有实际的regex匹配信息。

If you only want to run the regex once, you will have to roll you're own function which isn't too difficult.

如果您只想运行一次regex,那么您将不得不滚动自己的函数,这并不太难。

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 }

#4


2  

Yet another option

另一个选项

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

#5


2  

Having learnt a lot from all the other answers I was able to get what I want using the following line:

从其他答案中我学到了很多,我可以用下面这句话得到我想要的:

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

This felt nice as I was only running the regex once per line and as I was entering this at the command prompt it was nice not to have multiple lines of code.

这感觉很好,因为我每一行只运行一次regex,当我在命令提示符中输入它时,最好不要有多行代码。

#6


1  

See these notes on Regular expressions in PowerShell

请参阅PowerShell中正则表达式的这些说明

#7


1  

The Select-String command seems to return a MatchInfo variable and not a "string" variable. I spent several hours finding this out on forums and official website with no luck. I'm still gathering info. A way around this is to declare explicitly a string variable to hold the result returned from the Select-String, from your example:

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

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

[string] $foo = selectstring -path *。三种模式“主题=([a - z]+),“

The $foo variable is now a string and not a MatchInfo object.

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

Hope this helps.

希望这个有帮助。

ps5 powershell version 5 string strings manipulation

powershell版本5字符串操作

#8


0  

Another variation, matching 7 digits in a string

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

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

returns: 1234567

返回:1234567

#1


9  

I don't know why your version doesn't work. It should work. Here is an uglier version that works.

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

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

Edit. Explanation for dant:

编辑。次煤的解释:

-match is a regular expression matching operator:

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

>"foobar" -match "oo.ar"
True

The > $null just suppresses the True being written to the output. (Try removing it.) There is a cmdlet that does the same thing whose name I don't recall at the moment.

> $null只会抑制将True写入输出的情况。(试着删除。)有一个cmdlet做同样的事情,我一时想不起它的名字。

$matches is a magic variable that holds the result of the last -match operation.

$matches是一个神奇的变量,它保存上一次匹配操作的结果。

#2


4  

In PowerShell V2 CTP3, the Matches property is implemented. So the following will work:

在PowerShell V2 CTP3中,匹配属性被实现。因此,以下方法将有效:

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

#3


2  

The problem with the code you are typing is that select-string does not pass down the actual Regex object. Instead it passes a different class called MatchInfo which does not have the actual regex matches information.

您所键入的代码的问题是,selectstring不传递实际的Regex对象。相反,它通过一个名为MatchInfo的不同的类,它没有实际的regex匹配信息。

If you only want to run the regex once, you will have to roll you're own function which isn't too difficult.

如果您只想运行一次regex,那么您将不得不滚动自己的函数,这并不太难。

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 }

#4


2  

Yet another option

另一个选项

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

#5


2  

Having learnt a lot from all the other answers I was able to get what I want using the following line:

从其他答案中我学到了很多,我可以用下面这句话得到我想要的:

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

This felt nice as I was only running the regex once per line and as I was entering this at the command prompt it was nice not to have multiple lines of code.

这感觉很好,因为我每一行只运行一次regex,当我在命令提示符中输入它时,最好不要有多行代码。

#6


1  

See these notes on Regular expressions in PowerShell

请参阅PowerShell中正则表达式的这些说明

#7


1  

The Select-String command seems to return a MatchInfo variable and not a "string" variable. I spent several hours finding this out on forums and official website with no luck. I'm still gathering info. A way around this is to declare explicitly a string variable to hold the result returned from the Select-String, from your example:

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

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

[string] $foo = selectstring -path *。三种模式“主题=([a - z]+),“

The $foo variable is now a string and not a MatchInfo object.

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

Hope this helps.

希望这个有帮助。

ps5 powershell version 5 string strings manipulation

powershell版本5字符串操作

#8


0  

Another variation, matching 7 digits in a string

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

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

returns: 1234567

返回:1234567