|
HmJre.dllのV3.23以下で、例えば
xxx<foo>hoge<bar>baz
という文字列に対して、
xxx(<.+?>)+baz
がヒットしない問題ですが、他にもいろいろ調べたら、上記のような繰り返し
パターンの中に繰り返しパターンがあるようなケースでうまくヒットしないケー
スが多々あることが分かりました。がしかし、これについて根本的なアルゴリズ
ムから直していくのは大変ということで、アルゴリズム自体は変更せずに、別の
解決策を取ることにしました。
具体的には、例えば上記の (<.+?>) のような繰り返しを含む正規表現パ
ターンを、例えば(pattern)と表記するとしたら、
上記の例は、
(pattern)+
という風に表現出来ます。それを、
(pattern)(pattern)*
のように変換することにしました。こうするとHmJre.dllの正規表現エンジン
には一切変更を加えずに、うまくヒットするようになります。
その他も含めて変換法則を一通り書くと、
(pattern)+ --> (pattern)(pattern)*
(pattern)* --> (pattern|)(pattern)*
(pattern)+? --> (pattern)(pattern)*?
(pattern)*? --> (|pattern)(pattern)*?
(pattern){n} --> (pattern)(pattern)....
(pattern)がn回
(pattern){0,n} --> (pattern|)(pattern){n-1}
(pattern){n,} --> (pattern)(pattern)...(pattern){1,}
(pattern)がn-1回の後に(pattern){1,}
(pattern){n,m} --> (pattern)(pattern)...(pattern){1,m-n+1}
(pattern)がn-1回の後に(pattern){1,m-n+1}
(pattern)? --> (pattern|)
(pattern)?? --> (|pattern)
変換結果が (pattern){1}になった場合 --> (pattern)に変換。
変換結果が (pattern){0}になった場合 --> 削除。
のような変換をすることにしました。
ただし、{n} {n,} {n,m} のケースで、nが10を超えている場合には、1
つ1つに展開するのは10個まで、という風にしました。(でないととんでもなく
遅くて実用にならないので…)
ということで今それで大丈夫かどうかいろいろテストしている所ですが、もし
上記のようなやり方について、それではまずいケースがありますよ、とかのご意
見がありましたら、是非ともよろしくお願いしたい所です。
----------------参考テストデータ--------------------------
正規表現パターンの例: V3.23以下でヒットしない例
s(<.*?>)+z s<a>a<a>z
s(<.*?>)*z s<a>a<a>z
s(<.*?>){1,}z s<a>a<a>z
s(<.*>){2}z s<a><a>z
s(<.*>){1,}z s<a><a>z
s(<.*?>){1}z s<a><a>z
s(<.*?>)?z s<a><a>z
s(<.*?>)??z s<a><a>z
V3.24になっても繰り返し回数制限でダメな例:
(他の正規表現DLLだとハングアップします)
s(<.*>){50}z s<><><><><><>....(50個以上)...<><>z
|
|