web-dev-qa-db-ja.com

正規表現の$ /と$¢の違いは何ですか?

タイトルが示すように、$/の違いは何ですか?それらは常に同じ値を持っているように見えます:

my $text = "Hello world";

$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;

どちらも同じ値のMatchオブジェクトになります。どちらを使用する場合のロジックは何ですか?

13
user0721090601

変数_$/_は最新の一致を参照し、変数__は最新の最も外側の一致を参照します。上記のようなほとんどの基本的な正規表現では、それはまったく同じものになる可能性があります。ただし、_.raku_メソッドの出力からわかるように、Matchオブジェクトには他のMatchオブジェクトを含めることができます(これは、_$<foo>_または_$1_(キャプチャの場合)。

代わりに、定量化されたキャプチャを使用して次の正規表現があるとします

_/ ab (cd { say $¢.from, " ", $¢.to } ) + /
_

実行すると、「abcdcdcd」と照合すると、次の出力が表示されます。

_0 2
0 4
0 6
_

しかし、__の使用を_$/_に変更すると、異なる結果が得られます。

_2 2
4 4
6 6
_

(_.to_が少しずれているように見えるのは、それ(および_.pos_)がキャプチャブロックの終わりまで更新されないためです。)

言い換えると、__は最終的に一致するオブジェクト(つまり_$final = $text ~~ $regex_)を参照するalwaysとなるため、次のように正規表現内の複雑なキャプチャツリーを正確にトラバースできます。完全一致が完了したら、次のようになります。上記の例では、最初の一致を参照するために_$¢[0]_、2番目の一致を参照するために_$¢[1]_などを実行できます。

正規表現コードブロックの内部では、_$/_は最も近い一致を参照します。上記の場合、それは_( )_内の一致であり、他の一致についても、元の一致の開始についてもわかりません。_( )_ブロックの開始だけです。したがって、より複雑な正規表現を与えます:

_/ a $<foo>=(b $<bar>=(c)+ )+ d /
_

_$¢<foo>_と言うことで、$¢すべてのfooトークンを使用していつでもアクセスできます。 _$¢<foo>[0]<bar>_を使用して、特定のbarfooトークンにアクセスできます。 fooのキャプチャ内にコードブロックを挿入すると、_$<bar>_または_$/<bar>_を使用してbarトークンにアクセスできますが、これはできません。他のfoosにアクセスします。

13
user0721090601