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 }
(つまり、2番目の.Groups
なし)は同じ結果になります。
それを追加したいのですが、さらに試行すると、パイプされた| Select-Object -Property Groups
を削除することでコマンドを短縮できるようです。
以下をご覧ください
$a = "http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$'
$a
はMatchInfo
($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/
グループメンバーには、探しているものが見つかるので、次のように書くことができます。
"http://192.168.3.114:8080/compierews/" | Select-String -Pattern '^http://(.*):8080/(.*)/$' | % {"IP is $($_.matches.groups[1]) and path is $($_.matches.groups[2])"}
IP is 192.168.3.114 and path is compierews
このスクリプトは、ファイルのコンテンツから正規表現の指定されたキャプチャグループを取得し、その一致をコンソールに出力します。
_$file
_はロードするファイルです
_$cg
_は、取得するキャプチャグループです。
_$regex
_は正規表現パターンです
ロードするサンプルファイルとそのコンテンツ:
_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
_
_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 }
_