[regex]::Matches()
PSv3+ 構文を使用した、.NET メソッドに基づく簡潔なソリューション:
$str = @'
this is an "apple". it is red
this is an "orange". it is orange
this is an "blood orange". it is reddish
'@
[regex]::Matches($str, '".*?"').Value -replace '"'
正規表現は - で囲まれたトークンに".*?"
一致し、それらすべてを返します。それらを抽出し、文字を取り除きます。"..."
.Matches()
.Value
-replace '"'
"
これは、上記が1 行に複数の "..."
トークンがあっても機能することを意味します (ただし、エスケープされた文字 (例: ) が埋め込まれた トークンの抽出は機能しないことに注意してください)。"
\"
-match
(1 つの) 一致のみを検索する演算子の使用は、次の場合にのみオプションです。
- 入力を行に分割します
- 各行には最大で 1 つ
"..."
のトークンが含まれます (これは、質問のサンプル入力に当てはまります)。
PSv4+ ソリューションは次のとおりです。
# Split string into lines, then use -match to find the first "..." token
($str -split "`r?`n").ForEach({ if ($_ -match '"(.*?)"') { $Matches[1] } })
自動変数$Matches
には前の操作の結果が含まれ-match
(LHS がスカラーの場合)、インデックス[1]
には最初の (そして唯一の) キャプチャ グループ ( (...)
) が一致したものが含まれます。
-match
たとえば、という名前のバリアントがあれば-matchall
、次のように記述できると便利です。
# WISHFUL THINKING (as of PowerShell Core 6.2)
$str -matchall '".*?"' -replace '"'
GitHub でこの機能の提案を参照してください。