在 Powershell 中捕获正则表达式
Capturing Regex in Powershell
我正在解决这个问题。我想获取文本中所有匹配我的模式的 URL。应该包括 URL 的第一个参数,但不包括第二个参数。
两期:
- 它没有得到第一个 URL
- 我不知道捕获是如何工作的。
在方法 1 中,我看到了匹配项,但没有看到括号中的捕获文本。在方法 2 中,我在一些输出上看到了我的捕获,但得到了包含比我的捕获更多的额外输出。我喜欢方法 2 风格,但使用方法 1 是为了试图理解发生了什么,但只是给自己挖了一个更深的洞。
$fileContents = 'Misc Text < a href="http://example.com/Test.aspx?u=a1">blah blah</a> More Stuff <a href="http://example.com/Test.aspx?u=b2&parm=123">blah blah </a> Closing Text'
#Sample URL http://example.com/Test.aspx?u=a1&parm=123
$pattern = '<a href="(http://example.com/Test.aspx\?u=.*?)[&"]'
Write-Host "RegEx Pattern=$pattern"
Write-Host "----------- Method 1 --------------"
$groups = [regex]::Matches($fileContents, $pattern)
$groupnum = 0
foreach ($group in $groups)
{
Write-Host "Group=$groupnum URL=$group "
$capturenum = 0
foreach ($capture in $group.Captures)
{
Write-Host "Group=$groupnum Capture=$capturenum URL=$capture.value index=$($capture.index)"
$capturenum = $capturenum + 1
}
$groupnum = $groupnum + 1
}
Write-Host "----------- Method 2 --------------"
$urls = [regex]::Matches($fileContents, $pattern).Groups.Captures.Value
#$urls = $urls | select -Unique
Write-Host "Number of Matches = $($urls.Count)"
foreach ($url in $urls)
{
Write-Host "URL: $url "
}
Write-Host " "
输出:
----------- Method 1 --------------
Group=0 URL=<a href="http://example.com/Test.aspx?u=b2&
Group=0 Capture=0 URL=<a href="http://example.com/Test.aspx?u=b2&.value index=81
----------- Method 2 --------------
Number of Matches = 2
URL: <a href="http://example.com/Test.aspx?u=b2&
URL: http://example.com/Test.aspx?u=b2
Powershell 版本 5.1.17763.592
I'm missing how the capture works.
捕获组 0 始终 整个匹配 - 未命名的捕获组将编号为 1 到 9,因此您需要组 1。
我重命名了这些变量以使其含义更清楚:
$MatchList = [regex]::Matches($fileContents, $pattern)
foreach($Match in $MatchList){
for($i = 0; $i -lt $Match.Groups.Count; $i++){
"Group $i is: $($Match.Groups[$i].Value)"
}
}
如果您想收集所有捕获的 url,只需执行以下操作:
$urls = foreach($Match in $MatchList){
$Match.Groups[$i].Value
}
如果您只需要第一个匹配项,则无需手动调用 [regex]::Matches()
- PowerShell 会在您使用时自动将任何捕获组的字符串值注入自动 $Matches
变量-match
运算符,所以如果你这样做:
if($fileContents -match $pattern){
"Group 1 is $($Matches[1])"
}
# or
if($fileContents -match $pattern){
$url = $Matches[1]
}
...您将得到预期的结果:
Group 1 is http://example.com/Test.aspx?u=b2
使用带有参数 -AllMatches
的 Select-String
来获取输入字符串中的所有匹配项。您的正则表达式应如下所示:(?<=a href=")[^"]*
。这将匹配字符串 a href="
之后的任何不是双引号的字符(最后一个字符串不包含在匹配中)。现在你只需要扩展匹配的值就大功告成了。
$re = '(?<=a href=")[^"]*'
$fileContents |
Select-String -Pattern $re -AllMatches |
Select-Object -Expand Matches |
Select-Object -Expand Value
我正在解决这个问题。我想获取文本中所有匹配我的模式的 URL。应该包括 URL 的第一个参数,但不包括第二个参数。
两期:
- 它没有得到第一个 URL
- 我不知道捕获是如何工作的。
在方法 1 中,我看到了匹配项,但没有看到括号中的捕获文本。在方法 2 中,我在一些输出上看到了我的捕获,但得到了包含比我的捕获更多的额外输出。我喜欢方法 2 风格,但使用方法 1 是为了试图理解发生了什么,但只是给自己挖了一个更深的洞。
$fileContents = 'Misc Text < a href="http://example.com/Test.aspx?u=a1">blah blah</a> More Stuff <a href="http://example.com/Test.aspx?u=b2&parm=123">blah blah </a> Closing Text'
#Sample URL http://example.com/Test.aspx?u=a1&parm=123
$pattern = '<a href="(http://example.com/Test.aspx\?u=.*?)[&"]'
Write-Host "RegEx Pattern=$pattern"
Write-Host "----------- Method 1 --------------"
$groups = [regex]::Matches($fileContents, $pattern)
$groupnum = 0
foreach ($group in $groups)
{
Write-Host "Group=$groupnum URL=$group "
$capturenum = 0
foreach ($capture in $group.Captures)
{
Write-Host "Group=$groupnum Capture=$capturenum URL=$capture.value index=$($capture.index)"
$capturenum = $capturenum + 1
}
$groupnum = $groupnum + 1
}
Write-Host "----------- Method 2 --------------"
$urls = [regex]::Matches($fileContents, $pattern).Groups.Captures.Value
#$urls = $urls | select -Unique
Write-Host "Number of Matches = $($urls.Count)"
foreach ($url in $urls)
{
Write-Host "URL: $url "
}
Write-Host " "
输出:
----------- Method 1 --------------
Group=0 URL=<a href="http://example.com/Test.aspx?u=b2&
Group=0 Capture=0 URL=<a href="http://example.com/Test.aspx?u=b2&.value index=81
----------- Method 2 --------------
Number of Matches = 2
URL: <a href="http://example.com/Test.aspx?u=b2&
URL: http://example.com/Test.aspx?u=b2
Powershell 版本 5.1.17763.592
I'm missing how the capture works.
捕获组 0 始终 整个匹配 - 未命名的捕获组将编号为 1 到 9,因此您需要组 1。
我重命名了这些变量以使其含义更清楚:
$MatchList = [regex]::Matches($fileContents, $pattern)
foreach($Match in $MatchList){
for($i = 0; $i -lt $Match.Groups.Count; $i++){
"Group $i is: $($Match.Groups[$i].Value)"
}
}
如果您想收集所有捕获的 url,只需执行以下操作:
$urls = foreach($Match in $MatchList){
$Match.Groups[$i].Value
}
如果您只需要第一个匹配项,则无需手动调用 [regex]::Matches()
- PowerShell 会在您使用时自动将任何捕获组的字符串值注入自动 $Matches
变量-match
运算符,所以如果你这样做:
if($fileContents -match $pattern){
"Group 1 is $($Matches[1])"
}
# or
if($fileContents -match $pattern){
$url = $Matches[1]
}
...您将得到预期的结果:
Group 1 is http://example.com/Test.aspx?u=b2
使用带有参数 -AllMatches
的 Select-String
来获取输入字符串中的所有匹配项。您的正则表达式应如下所示:(?<=a href=")[^"]*
。这将匹配字符串 a href="
之后的任何不是双引号的字符(最后一个字符串不包含在匹配中)。现在你只需要扩展匹配的值就大功告成了。
$re = '(?<=a href=")[^"]*'
$fileContents |
Select-String -Pattern $re -AllMatches |
Select-Object -Expand Matches |
Select-Object -Expand Value