あるデータが「数字のみの文字列」であるかどうかのチェックに「/^[0-9]+$/」を使っていたところ、行末に「\n」が入っていた場合に、期待通りに動かないというワナにはまった。 具体的には、こんな感じ。
#!/usr/bin/php <?php $str = "1234\n"; if (preg_match('/^[0-9]+$/',$str)) { print "ok"; } else { print "ng"; } ?>
/^[0-9]+$/ は、「0から9の文字だけで構成された1文字以上の文字列」という意味なので、改行コードが入っている文字列 $str は「ng」になってくれそうな気がするのだが、現実は「ok」になる(常識?)
これ、PHP だけがこんな挙動なのかな?と思って、Perl / Ruby も調べてみたが同じ挙動だった。これはこれで正解ってことなんだろう、きっと。
それとは別のところで、PHP / Perl と Ruby とで挙動が違うモノがあったので、ちょっと書いてみる事にする。
まずは 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])) { print "ok\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\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\n" else print "ng\n" end }
これを実行すると、次のようになる。
$ ./test.php
ok
ok
ng
$ ./test.pl
ok
ok
ng
$ ./test.rb
ok
ok
ok
Ruby だけ、最後の "1234\n5678" という文字列も /^[0-9]+$/ でヒットする。PHP / Perl と Ruby のどちらが「正しい」のかは良く分からんけど、直感的には PHP / Perl の方を期待するなぁ。
ちなみに PHP にはいくつかの正規表現系があるのだけど、今回は(オレの趣味で)Perl 互換の正規表現を利用している。なので、Perl と動きが同じになっている(のだと思う)。他の正規表現系は試していない。
テストは Mac OS X Leopard 上で実施した。それぞれの言語系のバージョンは以下の通り。
$ /usr/bin/php --version PHP 5.2.4 (cli) (built: Sep 23 2007 22:34:35) Copyright (c) 1997-2007 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies $ /usr/bin/perl --version This is perl, v5.8.8 built for darwin-thread-multi-2level (with 1 registered patch, see perl -V for more detail) Copyright 1987-2006, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page. $ /usr/bin/ruby --version ruby 1.8.6 (2007-09-24 patchlevel 111) [universal-darwin9.0]
ジャパン スター・ウォーズ ドットコムの情報によると、テレビシリーズとして予定されていた「スター・ウォーズ クローン大戦」のファーストエピソード(第一話ってこと?)が劇場公開される事になったらしい。
北米での公開が今年の8月15日。日本を含む他国での公開日は近日発表との事。3ヶ月遅れくらいかなぁ。。。
こんにちは。/^([0-9]+)$/として$1を見てみると改行が含まれていないのではないかと思います。