2

スマートマッチ演算子 ( ~~) を使用してこれをどのように記述できますか?

use 5.010;

my $string = '12 23 34 45 5464 46';

while ( $string =~ /(\d\d)\s/g ) {
    say $1;
}
4

4 に答える 4

4

面白い。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」の近くの構文エラー

おそらく、上記のコードで無効な式が使用されている場合は、何かを言う必要があります

于 2009-10-28T15:40:55.283 に答える
1

これら 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)は の暗黙的なスマート マッチとして扱われ$_ます。
...

于 2009-10-29T04:26:49.257 に答える
0

最初の一致に無限に出力することが期待される動作ですか? それが、このコードが現在の形式で行う必要があることだからです。問題はスマートマッチ演算子ではありません。while ループは無限$stringです。グローバル スイッチは、/gループ自体を変更しません。

何を達成しようとしていますか?2 桁の値を 1 行に 1 つずつ出力することを想定しています。その場合、次のことを検討してください。

say join("\n", grep { /^\d{2}$/ } split(" ",$string));
于 2009-10-29T02:37:53.727 に答える
-1

正直なところ、これにスマートマッチ演算子を使用できるかどうかはわかりません。私の限られたテストでは、スマートマッチがマッチのリストではなくブール値を返しているようです。ただし、 (を使用して)投稿したコードは=~、それがなくても機能します。ループ
が原因で、投稿した内容が機能しません。whileループの条件ステートメントはwhile、各反復の開始前に実行されます。この場合、$string反復ごとにリセットされるため、正規表現はの最初の値を返します。foreachただし、Aは機能します。

my $string = '12 23 34 45 5464 46';
foreach my $number ($string =~ /(\d\d)\s/g) {
    print $number."\n";
}
于 2009-10-29T20:34:51.060 に答える