eregはPOSIX NFAエンジンじゃないっぽい
2007年4月29日
ereg関数ってのは、PHPの正規表現用の関数なんですが
この挙動がおかしいという話です。
この挙動がおかしいという話です。
「おかしい」ってのは、オライリーの正規表現本に書いてある内容と反しているってことです。
申し訳ありませんが、それ以外の基準を知らないので、用語とかもそれに準拠します。
で、何がおかしいかというと
例えば
例えば
<?php $p = '^(abc|[a-z]+)'; $s = 'abcdefghi' $m = array(); ereg($p, $s, $m); var_dump($m[1]); // 1番目のサブパターンにマッチした内容を出力する ?>
これを実行した場合に、
仮に従来型のNFAエンジンなら
最初にマッチングする”abc”が1番目のサブパターンのマッチとして格納されるはず。
また、POSIX準拠NFAエンジンなら、
最もマッチ範囲の大きい”abcdefghi”が1番目のサブパターンのマッチとして格納されるはず。
またまた、DFAエンジンなら、そもそもサブパターンによるマッチが出来ないはず。
ということで実行すると “abcdefghi”を出力するので、
「あー、やっぱりPOSIX NFAか」と思いましたが・・・が
念のため、↓的な、POSIX NFAの場合にフリーズするような奴で実行してみたら
「あー、やっぱりPOSIX NFAか」と思いましたが・・・が
念のため、↓的な、POSIX NFAの場合にフリーズするような奴で実行してみたら
<?php $p = '.*.*.*.*.*.*.*.*.*.*'; $s = 'aaaaaaaaaa' $m = array(); ereg($p, $s, $m); ?>
・・・あれ?すぐ返ってくるな。
んで、続けて調べていると
<?php $p = '123|[a-z]+'; $s = '123abcdef'; $m = array(); ereg($p, $s, $m); var_dump($m[0]); // "123"を出力 ?>
・・・?
POSIX NFA なら、”abcdef”を返すはずなんだけど・・・??
しつこく実行
<?php $p = 'abc|[a-z]+'; $s = '123abcdef'; $m = array(); ereg($p, $s, $m); var_dump($m[0]); // "abcdef"を出力 ?>
・・・??
アルファベット同士なら、長い方を返してくれるのかな??
どうにもereg関数は、
NFAとかPOSIXとか関係無しに、単なる独自仕様の関数っぽいです。
暇だったら、頑張ってCのソースでも追ってみようかと思います。
NFAとかPOSIXとか関係無しに、単なる独自仕様の関数っぽいです。
暇だったら、頑張ってCのソースでも追ってみようかと思います。
俺、C言語読めないジャン