如何从Select-String中获取捕获的组?

时间:2015-11-25 10:20:50

标签: regex powershell select-string select-object

我正在尝试使用Powershell(版本4)从Windows上的一组文件中提取文本:

PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | Format-Table

到目前为止,这么好。这给出了一组很好的MatchInfo个对象:

IgnoreCase                    LineNumber Line                          Filename                      Pattern                       Matches
----------                    ---------- ----                          --------                      -------                       -------
    True                            30   ...                           file.jsp                      ...                           {...}

接下来,我看到捕获是在匹配成员中,所以我把它们拿出来:

PS > Select-String -AllMatches -Pattern <mypattern-with(capture)> -Path file.jsp | ForEach-Object -MemberName Matches | Format-Table

给出了:

Groups        Success Captures                 Index     Length Value
------        ------- --------                 -----     ------ -----
{...}         True    {...}                    49        47     ...

| Format-List列表:

Groups   : {matched text, captured group}
Success  : True
Captures : {matched text}
Index    : 39
Length   : 33
Value    : matched text

这是我停下来的地方,我不知道如何进一步获取捕获的组元素的列表。

我尝试添加另一个| ForEach-Object -MemberName Groups,但它似乎与上面相同。

我得到的最接近的是| Select-Object -Property Groups,这确实给了我期望的东西(一组套装):

Groups
------
{matched text, captured group}
{matched text, captured group}
...

但是后来我无法从每个中提取捕获的组,我尝试使用| Select-Object -Index 1我只得到其中一个。

更新:可能的解决方案

似乎通过添加| ForEach-Object { $_.Groups.Groups[1].Value }我得到了我想要的东西,但我不明白为什么 - 所以我无法确定在将此方法扩展到以后我能够得到正确的结果整套文件。

为什么会有效?

作为旁注,此| ForEach-Object { $_.Groups[1].Value }(即没有第二个.Groups)会得到相同的结果。

我想补充一点,经过进一步的尝试,似乎可以通过删除管道| Select-Object -Property Groups来缩短命令。

5 个答案:

答案 0 :(得分:44)

看看以下

Map Bounds: , {"ne":{},"sw":{}}

$a = "http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$' 现在是$aMatchInfo),其中包含$a.gettype()属性。

Matches

在小组成员中,您将找到您要找的内容,以便您可以写下:

PS ps:\> $a.Matches
Groups   : {http://192.168.3.114:8080/compierews/, 192.168.3.114, compierews}
Success  : True
Captures : {http://192.168.3.114:8080/compierews/}
Index    : 0
Length   : 37
Value    : http://192.168.3.114:8080/compierews/

答案 1 :(得分:7)

根据Regular Expressions > Groups, Captures, and Substitutions上的powershell文档:

在使用-match运算符时,powershell将创建一个名为 $Matches

automatic variable
PS> "The last logged on user was CONTOSO\jsmith" -match "(.+was )(.+)"

此表达式返回的值仅为true | false,但是PS将添加$Matches hashtable

因此,如果输出$Matches,则将获得所有捕获组:

PS> $Matches

Name     Value
----     -----
2        CONTOSO\jsmith
1        The last logged on user was
0        The last logged on user was CONTOSO\jsmith

您可以使用点符号分别访问每个捕获组,如下所示:

PS> "The last logged on user was CONTOSO\jsmith" -match "(.+was )(.+)"
PS> $Matches.2
CONTOSO\jsmith

其他资源

答案 2 :(得分:1)

最新答案,但是要循环使用多个匹配项和组:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF=8">
        <title>Skull picker v3.2</title>
        <style>
            *{padding:0;margin:0}
            canvas {background:#ffffff;display:block;margin:0 auto}
        </style>
    </head>

    <body>

        <h1>The Halo Skull Picker</h1>
        <p>This is the first version of the Halo skull picker. Click the button below and it *should* give you a random selection of skulls to enable, if nothing shows up that would be no skulls</p>
        <p>Also as I further inprove this there will be options for every halo game</p>

        <button onclick="myFunction()">MCC Halo: CE Anniversary</button>

        <div id='here'></div>

    </body>
</html>

答案 3 :(得分:0)

此脚本将从文件内容中获取正则表达式的指定捕获组,并将其匹配项输出到控制台。


$file是您要加载的文件
$cg是您要捕获的捕获组
$regex是正则表达式模式



示例文件及其要加载的内容:

C:\ some \ file.txt

This is the especially special text in the file.



示例用法:.\get_regex_capture.ps1 -file "C:\some\file.txt" -cg 1 -regex '\b(special\W\w+)'

输出:special text


get_regex_capture.ps1

Param(
    $file=$file,
    [int]$cg=[int]$cg,
    $regex=$regex
)
[int]$capture_group = $cg
$file_content = [string]::Join("`r`n", (Get-Content -Raw "$file"));
Select-String -InputObject $file_content -Pattern $regex -AllMatches | % { $_.Matches.Captures } | % { echo $_.Groups[$capture_group].Value }

答案 4 :(得分:0)

这适合我的情况。

使用文件: test.txt

// autogenerated by script
char VERSION[21] = "ABCDEFGHIJKLMNOPQRST";
char NUMBER[16] = "123456789012345";

从文件中获取数字和版本。

PS C:\> Select-String -Path test.txt -Pattern 'VERSION\[\d+\]\s=\s\"(.*)\"' | %{$_.Matches.Groups[
1].value}

ABCDEFGHIJKLMNOPQRST

PS C:\> Select-String -Path test.txt -Pattern 'NUMBER\[\d+\]\s=\s\"(.*)\"' | %{$_.Matches.Groups[1
].value}

123456789012345