0

私は以下のような正規表現を持っています:

$regex = qr/(?sx-im:(?sx-im:(?:^|(?<=\n)))(?=(?sx-im:[\ \t]*)(?sx-im:(?:^|(?<=\n))Data\ and\ value)(?sx-im:[\ \t\r]*(?:$|\n))))/;

次のテキストと照合しています。

$text ="Data and value";

ここで、試合開始オフセット、試合終了オフセット、および一致したテキストを取得したいと考えています。

通常、私は を使用し@-、これらを以下のように取得します。@+$&

if($text  =~ m/$regex/) 
{
        print "START Offset = ".$-[0];
        print "END Offsset  = ".$+[0];
        print "Matched Text = ".$&;
}

この場合、一致は成功しますが、正しいオフセットと一致するテキストを取得できません。0試合開始オフセットと試合終了オフセットの両方として印刷するだけです。そして、一致したテキストの印刷は空です。

この正規表現のさまざまなコンポーネントを理解したいです。具体的にはこれ(?sx-im:とは何か、一致したテキストを取得する方法

そのような正規表現の理由を私に尋ねたり、正規表現を変更するよう提案したりしないでください。これは、ソフトウェアで生成された正規表現です。質問のために問題を単純化しました。

この正規表現の理解を開始し、一致オフセットを取得する場所を教えてください。

4

2 に答える 2

4

バグは、一致オフセットの理解ではなく、正規表現にあります。文字列の先頭で幅がゼロの文字列に一致し、開始オフセットと終了オフセットが 0 であることを正しく報告しています。

なぜこれに一致するのかは、別の良い質問ですこのように正規表現を分割できます(テストされていません):

qr/(?sx-im:
  (?sx-im:(?:^|(?<=\n)))
  (?=(?sx-im:[\ \t]*)(?sx-im:(?:^|(?<=\n))Data\ and\ value)(?sx-im:[\ \t\r]*(?:$|\n)))
)/x

そして、2 つの連続する半分を見ることができます。

  • 1 つ目は、行頭または後読み一致に一致し\nます。つまり、どちらもゼロ幅です。
  • 2 番目は、大量の要素全体の先読み一致ですが、これも幅ゼロの一致です。

特に行頭と行末を一致させるために、正規表現を使いすぎているようです。ソース ファイルを 1 行ずつ読み取って個々の行を処理することを検討してください。

于 2012-11-07T14:03:23.223 に答える
4

(?: ... )非キャプチャ グループです。後方参照は作成されません。

同様に、(?= ... )はゼロ幅の先読みアサーションです。一致する文字列は に含まれません$&

拡張パターンを参照してください。

于 2012-11-07T13:49:15.560 に答える