12

以下のプリントac | a | bbb | c

    #!/usr/bin/env perl
    use strict;
    use warnings;
    # use re 'debug';
    
    my $str = 'aacbbbcac';
    
    if ($str =~ m/((a+)?(b+)?(c))*/) {
       print "$1 | $2 | $3 | $4\n";
    }

失敗した一致は、キャプチャされたグループ変数をリセットしないようです。私は何が欠けていますか?

4

3 に答える 3

21

失敗したマッチはキャプチャされたグループ変数をリセットしないようです

そこに失敗した一致はありません。あなたの正規表現は文字列とうまく一致します。いくつかの繰り返しで、内部グループの一致に失敗することがいくつかありますが。一致した各グループは、その特定のグループで見つかった次の一致によって上書きされるか、そのグループが現在の繰り返しで一致しない場合、以前の一致の値を保持する可能性があります。

正規表現の一致がどのように進行するか見てみましょう:

  • 最初(a+)?(b+)?(c)の一致aac。はオプションであるため(b+)?、一致しません。この段階で、各キャプチャ グループには次の部分が含まれます。

    • $1マッチ全体を含む -aac
    • $2一部を含む(a+)?-aa
    • $3(b+)?の部分が含まれていますnull
    • $4一部を含む(c)-c
  • 一致する文字列がまだ残っているため - bbbcac。さらに進む -(a+)?(b+)?(c)マッチ - bbbc. はオプションであるため(a+)?、一致しません。

    • $1一致全体が含まれます - bbbc。以前の値を上書きします$1
    • $2一致しません。したがって、以前に一致したテキストが含まれます-aa
    • $3今回はマッチ。を含む -bbb
    • $4マッチc
  • 繰り返し(a+)?(b+)?(c)ますが、最後の部分に一致します - ac

    • $1一致全体が含まれます - ac
    • $2a今回はマッチ。の以前の値を上書きします$2。それは今含まれています -a
    • $3今回は(b+)?パーツがないので一致しません。前の試合と同じになります -bbb
    • $4一致しcます。前の一致の値を上書きします。現在は - が含まれていますc

これで、文字列には一致するものは何も残っていません。すべてのキャプチャ グループの最終的な値は次のとおりです。

  • $1-ac
  • $2-a
  • $3-bbb
  • $4- c.
于 2013-10-28T18:27:33.487 に答える