【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系で発生する環境依存問題の疑いが濃くなった。


プロフィール

コヤナギ トモヤ

ウェブ系エンジニアしてます。ウェブデザイナー、ウェブディレクターとしてウェブ制作の仕事に携わり、今はエンジニア職に流れ着きました。誰かのお仕事をちょっとだけ効率化するような支援ツールの開発が好き。オープンソースとMITライセンス大好き。人生後半は自由と民主主義のコントリビューターとして過ごす予定。

ウェブ制作支援ツール Pickles 2 をオープンソースで開発しています。

PHP/JavaScript/NodeJS/nwjs/Laravel/Pickles2/オープンソース/心理学/倫理/自由と民主主義

RSSフィード

ページの先頭へ戻る