【PHP】 preg_match() の最小マッチに容量制限がある?

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.txtlongfile_ng.txt をマッチさせているが、longfile_ok.txt では成功していて、 longfile_ng.txt では失敗している。この2つのファイルは、当たり障りなさそうな1バイトしか違いがない。

この実験では、1つ目の最小マッチにマッチできる長さは、49996バイトが上限であるように見える。

ところが、このパターンの部分を、

/^(.*)(?:end)(.*)$/s

とか、

/^(.*?)end(.*)$/s

に書き換えてみると、longfile_ng.txt にもマッチできるよになるようだ。
"end" の部分をサブパターンじゃなくすると最小マッチが49997バイトにマッチできるようになっているので、「最小マッチの上限 = 49996バイト」 と単純には言えそうにない。

なぜこうなるのか、理由はよくわからない。49996バイトという上限(?)も、たまたま僕の環境でその数字だっただけかも知れない。この問題が発現した環境は下記。

  • Windows Vista + XAMPP
  • PHP 5.2.5
  • Apache 2.2.6

試しに他の環境で動かしてみた。

  • UNIX系OS+PHP4系の環境で試したら、問題の挙動は起きなかった(4MBくらいにマッチさせてみても平気)。
  • UNIX系OS+PHP5.2.9 の環境では発現した。

というわけで、どうやら PHP5系で発生する環境依存問題の疑いが濃くなった。


プロフィール

ときにはデザイナ、ときにはディレクタ、ときにはプログラマ、ときには何でも屋と、ウェブの世界で未熟ながらもいろいろやっている、コヤナギトモヤです。

ツイッター上ではこのヒト。
@tomk79

RSSフィード

ページの先頭へ戻る