Perl の正規表現グループ: 文字列から未知の数/複数/可変の出現に一致する正規表現グループから要素を配列にキャプチャする方法は? 質問する

Perl の正規表現グループ: 文字列から未知の数/複数/可変の出現に一致する正規表現グループから要素を配列にキャプチャする方法は? 質問する

Perl では、1 つの正規表現のグループ化を使用して、それに一致する複数の出現を複数の配列要素にキャプチャするにはどうすればよいですか?

たとえば、文字列の場合:

var1=100 var2=90 var5=hello var3="a, b, c" var7=test var3=hello

これをコードで処理するには:

$string = "var1=100 var2=90 var5=hello var3=\"a, b, c\" var7=test var3=hello";

my @array = $string =~ <regular expression here>

for ( my $i = 0; $i < scalar( @array ); $i++ )
{
  print $i.": ".$array[$i]."\n";
}

出力として以下を確認したいと思います:

0: var1=100
1: var2=90
2: var5=hello
3: var3="a, b, c"
4: var7=test
5: var3=hello

正規表現として何を使用すればよいでしょうか?

ここで一致させたいものの共通性は割り当て文字列パターンなので、次のようになります。

my @array = $string =~ m/(\w+=[\w\"\,\s]+)*/;

* は、グループに一致する 1 つ以上の出現を示します。

(一部の一致にはスペースが含まれているため (つまり、var3...)、望ましい結果が得られないため、split() の使用は除外しました。)

上記の正規表現では、次の結果のみが得られます。

0: var1=100 var2

正規表現で可能ですか? それとも追加コードが必要ですか?

「perl regex multiple group」を検索したときに既存の回答を確認しましたが、手がかりが足りません。

ベストアンサー1

my $string = "var1=100 var2=90 var5=hello var3=\"a, b, c\" var7=test var3=hello";

while($string =~ /(?:^|\s+)(\S+)\s*=\s*("[^"]*"|\S*)/g) {
        print "<$1> => <$2>\n";
}

プリント:

<var1> => <100>
<var2> => <90>
<var5> => <hello>
<var3> => <"a, b, c">
<var7> => <test>
<var3> => <hello>

説明:

最後の部分を先にします。g末尾のフラグは、正規表現を文字列に複数回適用できることを意味します。2 回目は、文字列内の最後の一致が終了した場所から一致が続行されます。

次は正規表現です。 は、(?:^|\s+)文字列の先頭または 1 つ以上のスペースのグループに一致します。 これは、正規表現が次回適用されるときに、キーと値のペア間のスペースをスキップするために必要です。 は、?:括弧の内容がグループとしてキャプチャされないことを意味します (スペースは不要で、キーと値のみが必要です)。\S+は変数名に一致します。 次に、間にある任意の数のスペースと等号をスキップします。 最後に、 は、間に任意の("[^"]*"|\S*)/数の文字がある 2 つの引用符、または値に対する任意の数の非スペース文字に一致します。 引用符の一致は非常に脆弱であり、エスケープされた引用符を適切に処理しないことに注意してください。たとえば、"\"quoted\""は になります"\"

編集:

実際には、単一のキー/値ではなく、割り当て全体を取得したいので、それらを抽出するワンライナーを次に示します。

my @list = $string =~ /(?:^|\s+)((?:\S+)\s*=\s*(?:"[^"]*"|\S*))/g;

おすすめ記事