スマートマッチ演算子 ( ~~
) を使用してこれをどのように記述できますか?
use 5.010;
my $string = '12 23 34 45 5464 46';
while ( $string =~ /(\d\d)\s/g ) {
say $1;
}
スマートマッチ演算子 ( ~~
) を使用してこれをどのように記述できますか?
use 5.010;
my $string = '12 23 34 45 5464 46';
while ( $string =~ /(\d\d)\s/g ) {
say $1;
}
面白い。perlsynは次のように述べています。
正規
~~
表現パターンの一致$a =~ /$b/
したがって、一見すると、期待するのは合理的なようです
use strict; use warnings;
use 5.010;
my $string = '12 23 34 45 5464 46';
while ( $string ~~ /(\d\d)\s/g ) {
say $1;
}
12
、などを印刷します23
が、ループでスタックし、12
繰り返し一致します。使用:
$ perl -MO = Deparse y.pl
収量
while ($string ~~ qr/(\d\d)\s/g) {
say $1;
}
perlopを見ると、気づきます
qr/STRING/msixpo
'g'は修飾子としてリストされていないことに注意してください(論理的には)。
興味深いことに、あなたが書く場合:
my $re = qr/(\d\d)\s/g;
perl
バーフ:
ベアワードは、演算子がC:\ Temp \y.pl5行目で予期された場所で見つかりました。 「qr/(\ d \ d)\ s/g」の近く C:\ Temp \ y.plの5行目、「qr /(\ d \ d)\ s/g」の近くの構文エラー
おそらく、上記のコードで無効な式が使用されている場合は、何かを言う必要があります
これら 2 つの亜種が何に変換されるかを調べてみると、その理由がわかります。
まずはオリジナル版を見てみましょう。
perl -MO=Deparse -e'while("abc" =~ /(.)/g){print "hi\n"}'
while ('abc' =~ /(.)/g) {
print "hi\n";
}
ご覧のとおり、オペコードの変更はありませんでした。
スマートマッチ演算子を使用するように変更すると、実際に変更されることがわかります。
perl -MO=Deparse -e'while("abc" ~~ /(.)/g){print "hi\n"}'
while ('abc' ~~ qr/(.)/g) {
print "hi\n";
}
qr
オプションを認識しないに変更し/g
ます。
これによりおそらくエラーが発生するはずですが、解析されるまで変換されません。
qr
あなたが得るべきであり、代わりに使用した場合に得られる警告は次のとおりです。
-e 行 1、「qr/(.)/g」付近の構文エラー
スマートマッチ機能は、=~
オペレーターに取って代わることを意図したものではありませんでした。given
それは、それがそうであるように/when
作るプロセスから生まれました.
ほとんどの場合、
when(EXPR)
は の暗黙的なスマート マッチとして扱われ$_
ます。
...
最初の一致に無限に出力することが期待される動作ですか? それが、このコードが現在の形式で行う必要があることだからです。問題はスマートマッチ演算子ではありません。while ループは無限$string
です。グローバル スイッチは、/g
ループ自体を変更しません。
何を達成しようとしていますか?2 桁の値を 1 行に 1 つずつ出力することを想定しています。その場合、次のことを検討してください。
say join("\n", grep { /^\d{2}$/ } split(" ",$string));
正直なところ、これにスマートマッチ演算子を使用できるかどうかはわかりません。私の限られたテストでは、スマートマッチがマッチのリストではなくブール値を返しているようです。ただし、 (を使用して)投稿したコードは=~
、それがなくても機能します。ループ
が原因で、投稿した内容が機能しません。while
ループの条件ステートメントはwhile
、各反復の開始前に実行されます。この場合、$string
反復ごとにリセットされるため、正規表現はの最初の値を返します。foreach
ただし、Aは機能します。
my $string = '12 23 34 45 5464 46';
foreach my $number ($string =~ /(\d\d)\s/g) {
print $number."\n";
}