公開日: 2009年11月12日(Thu)
PHP の preg_match()
で最小マッチパターンを使ったときに、長い文字列にマッチできないような現象に出くわしたのでメモる。
ちょっと調べてみはしたが、原因はよくわからない。ただし、環境に依存して発現するようだ。
問題のコードは下記のようなパターンで起きている。
/^(.*?)(?:end)(.*)$/s
このパターンで、下記のように実装した。
$preg_pattern = '/^(.*?)(?:end)(.*)$/s';
$bin = file_get_contents( './longfile_ok.txt' );
$result = preg_match( $preg_pattern , $bin , $mathed );
詳しくは実際にやってみたサンプルを確認されたし。
まったく同じパターンを使って、longfile_ok.txt
と longfile_ng.txt
をマッチさせているが、longfile_ok.txt
では成功していて、 longfile_ng.txt
では失敗している。この2つのファイルは、当たり障りなさそうな1バイトしか違いがない。
この実験では、1つ目の最小マッチにマッチできる長さは、49996バイトが上限であるように見える。
ところが、このパターンの部分を、
/^(.*)(?:end)(.*)$/s
とか、
/^(.*?)end(.*)$/s
に書き換えてみると、longfile_ng.txt
にもマッチできるよになるようだ。
"end" の部分をサブパターンじゃなくすると最小マッチが49997バイトにマッチできるようになっているので、「最小マッチの上限 = 49996バイト」 と単純には言えそうにない。
なぜこうなるのか、理由はよくわからない。49996バイトという上限(?)も、たまたま僕の環境でその数字だっただけかも知れない。この問題が発現した環境は下記。
試しに他の環境で動かしてみた。
というわけで、どうやら PHP5系で発生する環境依存問題の疑いが濃くなった。
公開日: 2009年11月12日(Thu)