/gcと\Gを使って複数の正規表現式でトークンを少しずつ削りとる
複数の正規表現式で文字列からトークンを切り出したいことがある。しかし、以下のコードは動かない。無限ループになってしまう。
#!perl -w # THIS DOES NOT WORK!!! use 5.10.0; use strict; use utf8; my $s = 'foo bar baz FOO BAR BAZ'; while( 1 ) { if( $s =~ /\b (f..) \b/xmsig) { # first matching expression say $1; } elsif( $s =~ /\b (b..) \b/xmsig) { # second matching expression say $1; } else { die 'finished'; } }
これは[twitter:@akajiro]さんと[twitter:@hio]さんに教えてもらった結果、解決した。つまり、正規表現修飾子/cと、前回のマッチ位置を意味するメタ文字\Gを使えばいい。動作するコードは以下のようになる。
#!perl -w use 5.10.0; use strict; use utf8; my $s = 'foo bar baz FOO BAR BAZ'; while( 1 ) { if( $s =~ /\G \s* \b (f..) \b/xmsigc) { # first matching expression say $1; } elsif( $s =~ /\G \s* \b (b..) \b/xmsigc) { # second matching expression say $1; } else { die 'finished'; } }
空白を読み飛ばすための\s*
をいれているほかは特に工夫はない。
参考文献: perlre