hnw さんからツッコミを貰ったので、昨日のコードをちょっと改造して、マッチしている部分をチェックしてみた。
PHP のコード。test.php。
#!/usr/bin/php <?php $array = array('1234', '1234' . "\n", '1234' . "\n" . '5678'); for ($i = 0; $i < count($array); ++$i) { if (preg_match('/^([0-9]+)$/',$array[$i],$match)) { print "ok: " . $match[1] . "\n"; } else { print "ng\n"; } } ?>
Perl 版。test.pl。
#!/usr/bin/perl @array = ('1234', '1234' . "\n", '1234' . "\n" . '5678'); for ($i = 0; $i < @array; $i++) { if ($array[$i] =~ /^([0-9]+)$/) { print "ok: " . $1 . "\n"; } else { print "ng\n"; } }
Ruby 版。test.rb。
#!/usr/bin/ruby array = ['1234', '1234' + "\n", '1224' + "\n" + '5678']; array.each { |tmp| if /^([0-9]+)$/ =~ tmp then print "ok: " + $1 + "\n" else print "ng\n" end }
で、実行結果。
$ ./test.php ok: 1234 ok: 1234 ng $ ./test.pl ok: 1234 ok: 1234 ng $ ./test.rb ok: 1234 ok: 1234 ok: 1224
PHP / Perl / Ruby とも文字列の末尾に「\n」が入っているいないに関わらず同じ結果になった。文字列中に「\n」が入っている場合、Ruby だけが 1234 にマッチしていた。
これはつまり、Ruby における正規表現は PHP / Perl での m オプション付きと同じ動きなのかしら?
ということで、オプションを付けて実行してみた。
#!/usr/bin/php
<?php
$array = array('1234',
'1234' . "\n",
'1234' . "\n" . '5678');
for ($i = 0; $i < count($array); ++$i) {
if (preg_match('/^([0-9]+)$/m',$array[$i],$match)) {
print "ok: " . $match[1] . "\n";
} else {
print "ng\n";
}
}
?>
#!/usr/bin/perl
@array = ('1234',
'1234' . "\n",
'1234' . "\n" . '5678');
for ($i = 0; $i < @array; $i++) {
if ($array[$i] =~ /^([0-9]+)$/m) {
print "ok: " . $1 . "\n";
} else {
print "ng\n";
}
}
$ ./test.php ok: 1234 ok: 1234 ok: 1234 $ ./test.pl ok: 1234 ok: 1234 ok: 1234
この結果だけみると、PHP / Perl と Ruby とで同じ状態にはなったんだが、「Ruby の正規表現は Perl における m オプション付きがデフォルト動作」という認識は正しいのだろうか?
えー、Perlのmオプションについては良く知らないのですが、Rubyでは$は行末にマッチであり、文字列末尾ではありません(文字列末尾は\z)。<br>↓このページが詳しいかも。<br>http://jp.rubyist.net/magazine/?0021-BundledLibraries
思いつきレベルでコメントさせて頂いたんですが、解決したみたいですね。<br><br>\zはPerl 5.005から導入されているそうです。また、\Zってのもあるそうで。僕は随分昔からPerlをやってるはずなんですが、恥ずかしながら先ほど知りました。<br><br>$は0文字にマッチするような気がしちゃうんですけど、実は文字列最後の\nに限っては1文字にマッチするんですよね。-peしたときにchompしなくてもsedと同じ動作をさせるようなPerlの発明なのかもしれませんが、それだと不便な人もいるから行末や文字列末尾の0文字にマッチする記号が導入されたんでしょうかね。
すみません、誤解してました。やっぱり$はいつでも0文字マッチなんですね。普段は最後の文字の次の0文字にマッチ、文字列最後の文字が\nのときだけ\nの直前の0文字にマッチ、なんですね。今までずっと誤解していたようです…。