1

次のフォーマットされたサンプル文字列があります。

== header == information about things ==headeragain== info can have characters like.*?{=

などを一行で。

キーが「==.+?==」で、値がキーの後の情報になるように、これをハッシュに解析したいと思います。これらのペアをグローバルに一致させるために、いくつかの正規表現を試しました。

%hash = $string =~ /(==.+?==)(.+)/g

%hash = $string =~ /(==.+?==)(.+?)/g

最初のキーに一致し、次にその値として他のすべてに一致し、それぞれのキーだけに一致します。

%hash = $string =~ /(==.+?==)(.+(?===.+?==))/g

次の鍵を先取りすることになっていますが、私が理解しているように「食べ尽くす」ことはありません。ただし、最初のペアのみに一致し、それ以上は進みません。

この問題は、グローバル修飾子がどのように機能するかについての誤解から生じたと思います。エクスプレッションの 1 つを微調整する必要がありますか? それとも、まったく違うことをする必要がありますか?

4

2 に答える 2

1
while ($line =~ /
   == \s*
   ( .+? )
   \s* == \s*
   ( .*? )
   (?= \s* (?: == | \z ) )
/xg) {
   my $key = $1;
   my $val = $2;
   ...
}

?しかし、私は " " 量指定子修飾子を使うのが嫌いです。間違った、または予期しない入力が与えられたときに、間違ったものが一致するのを実際に防ぐことはできません。だから私は使用します:

while ($line =~ /
   == \s*
   ( \S (?: (?! \s* == ). )* )
   \s* == \s*
   ( (?: (?! \s* == ). )* )
/xg) {
   my $key = $1;
   my $val = $2;
   ...
}
于 2012-04-07T20:42:22.647 に答える
1

貪欲でない修飾子を使用している場合でも、2 番目の例では 2 番目のサブグループに制限はありません。

値の後に肯定的な先読みを追加(?=$|==)します。これは先読み(?=ブロックの宣言であり、$または==検索している部分文字列です。

つまり、解決策は次のとおりです。/(==.+?==)(.+?)(?=$|==)/g

于 2012-04-07T20:33:57.683 に答える