Delphi6での正規表現

解決


まこと  2011-12-16 06:05:33  No: 41365

いつもおせわになっております。
ここで聞いたものかちょっと悩んだのですが、作者さんとの連絡がうまく取れないので、質問させてください。

私は、Delphi6で正規表現を使用する際、次のコンポーネントを使用させていただいています。

正規表現を使った文字列探索/操作コンポーネント集
http://homepage1.nifty.com/bmonkey/delphi/delphi.html

ここで本日、AWKStrというコンポーネントのRegExpプロパティにある文字列を入れ、検索を実行しようと
したところ、まるで無限ループに入ったかのように、ソフトがフリーズしてしまいました。

その時指定した文字列は次の文字列になります。
^[^(displayname)]

このコンポーネントは、Delphi6でも使える、数少ない正規表現ライブラリです。自作のソフトでもかなり使用させていただいて
いるソフトですので、この「検索文字列を指定しただけでフリーズしてしまう」という現象をなんとかして乗り切りたいと
考えております。何か情報をお持ちの方、わかりましたらどんな些細なことでも結構ですので、情報提供をお願いいたします。


けど  2011-12-16 07:46:33  No: 41366

私もずっと AWKStr を使っていましたが
結局 TRegExpr に全て移行しました(きっかけは忘れました)
Delphi5 でも使用可能です


tor  2011-12-16 07:55:10  No: 41367

直接の答えになるかどうかわかりませんが、その正規表現の指定は何だかおかしいですね。
[] は文字クラスの指定、[^] はその補集合ですから
「先頭の1文字が '(', 'd', 'i', 's', 'p', 'l',
'a', 'y', 'n', 'a', 'm', 'e', ')' のどれでもない」
という意味になります。

で、そのコンポーネントを持ってきて試してみたところ、
補文字クラスの中に、ASCIIコードの連続する3つの文字が
1番目、3番目、2番目の順番で出てくるとフリーズするようです。
[^abc] →OK
[^acb] →フリーズ
問題の文字列だと 'l', 'n', 'm' がこの順で出てきているのが原因ですね。

たぶん、クラスの中で重複する文字をまとめるところにバグがあるのかと思いますが
とりあえず、文字クラスの内部では並び順は関係ないので
^[^adeilmnpsy()] のようにコード順に並べ直せば回避はできます。


tor  2011-12-16 23:45:20  No: 41368

ついでに、ソースが同梱されていたので軽く追ってみました。

問題は、bmregexp.pas - TREParser.NegativeCharacterClass の中にあるRemoveCC関数で
分割後のノードが両方nilだった場合のケアをしていないことですね。
この場合、そのノードは分割できなかった(その必要がなかった)ということなので、まるまる取り除いて構わないはず。
(取り除かないと、先に進まずに同じノードを延々調べ続けることになります)
> if (pNode1 <> nil) or (pNode2 <> nil) then begin
という行(と対応するend文)を外せば直るのではないかと思います。


まこと  2011-12-17 04:13:44  No: 41369

早々の回答、どうもありがとうございます。
  今ちょっとやってみました。…うまくいきました!
本当にどうもありがとうございます。念のため、もう少し様子を見て、
そのうえでまた報告いたします。正規表現は使ったことはあっても
原理までは全然知りませんでしたので、本当に助かりました。

それと、TRegExprの方なのですが、しばらく前に公開停止になっていた
と聞いていたのですが、最近サイト復活したのでしょうか。
先ほどダウンロード可能になっていました。こちらも後方参照が使える
分、より便利かもしれませんね。
使い方がよくわからないのですぐには組み込めませんが、今後使う
ことも十分想定されますので、これを機会に触ってみたいと思います。


まこと  2011-12-28 06:23:18  No: 41370

あの後、しばらく使って様子を見ていたのですが、動作は良好でした。
そのため、チェックをつけさせていただきます。
直接の回答をくださったtor様、本当にどうもありがとうございました。
あなたには感謝してもしきれません。お答えをいただけていなかったら、
かなりの時間を要して、ほかの正規表現コンポーネントに乗り換えざるを
得なかったと思います。本当に助かりました。どうもありがとうございました。

それと、その他の正規表現コンポーネントについてご紹介くださったけど様、
前から私も後方参照の便利さは実感しているところですので、時間はかかり
ますが、そのコンポーネントの使い方をマスターしてみたいと思います。
何かあったときは、この場で質問させていただくかもしれませんが、
その際も、ぜひどうぞよろしくお願いいたします。

お二人と皆様方、どうもありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加