! [SakuraEditor][正規表現] 「鬼車と bregonigに hitEnd([[20100531p01]])機能が搭載されることを願う他力本願日記」 なんてことをこの日記の冒頭に掲げたもんだから自分でやってみた(どういうこと?)。 !!更新履歴 :{{file 'rev2', :href=>'rev2.txt'}} (2010-08-27, 最新) ::(サクラエディタ) 複数行検索モード実装。(正規表現を使った下検索のみ。50MiB制限あり。制限による探索打ち切り・マッチ範囲切り上げの通知なし) ::テストバイナリ+変更点({{file 'test_multiine_search.zip'}}) :{{file 'rev1', :href=>'rev1.txt'}} ::(鬼車) 普通のマッチなしと、入力次第でマッチする可能性のあるマッチなしに異なる戻り値を割り当てた。 ::(bregonig) 入力不足のときに BMatchの戻り値を 0(正常終了,マッチなし)にして、エラーメッセージでを伝えている。 ::(サクラエディタ) 下検索での入力不足によるマッチ失敗をステータスバーで通知。 !!bregonig 既存アプリに影響があるので良くないけど、bregonigへの暫定的な変更はこう。 !!!regexec_onig(bregonig.cpp) <<>> 入力が足りなくてマッチしなかったときは、エラーメッセージをセットするけど戻り値は負数(エラー)ではなく 0(マッチなし)。 !!鬼車 鬼車(5.9.2)に「[[K.Takata's software : bregonig.dll|http://homepage3.nifty.com/k-takata/mysoft/bregonig.html]]」で手に入る onig-5.9.2-mod.diffを適用したものをさらに変更。マッチに失敗したときのエラーの種類で hitendしたかどうかを伝える。ちゃんと動くのか非常にあやしい代物。TODOもいっぱいある。 * 特定のパターンのパターンに向けた最適化を無効にしている。(そこまで手が回らない) * backwward searchに対していつ hitendフラグを立てていいのかわからない。(ので未対応) * "aaaaa\n" という文字列から [a\r\n]+a というパターンを検索したときにバックトラックにより "aaaaa" がマッチするわけだが、その次の行にも "aaaa.." という文字が続いていた場合は……。一応マッチは見つかっているが hitendフラグも立てたい。 * [\w\W\s\S] というようなパターンで、メタ文字の登場順([\W\S\w\s]とか)に 依存しておかしな結果になる。(もちろん俺のミス。原因は解らない) やっぱり鬼車は手に負えないかも。 !!サクラエディタ なんのことはない、影響を受ける既存アプリにはサクラエディタが含まれている。正規表現のコンパイルエラーと入力不足によるマッチなしを区別するためにちょっと変更した。 !!!複数行検索モード 一行検索(従来動作)してみて、マッチが行末まで続いていたり次の行の内容次第でマッチが成功に変わりそうなときはとりあえず二行ぶん検索してみる。それでも状況が同じなら 50MiBのバッファを埋めてから三度目の検索を行う。50MiBって大きすぎるだろうか。大きさの問題だろうか。かかか。 実装は CSearchAgent::SearchWord()に。これって単語検索専用のメソッドではなかったのですよ。[[CGrepAgent|https://sourceforge.net/tracker/?func=detail&aid=3008500&group_id=12488&atid=1013762]]もこれを利用したらよかった。 バッファの実体は std::wstringで。文字列を比較するにも wmemcmpなりを使おうとして結局 ``std::wstring("hoge") == L"hoge"`` を使ったへたれなので、str系のライブラリ関数は恐ろしくて毎回すぐに投げ出します。 !!!TODO * 上検索。 * 検索語ハイライトの処理がたぶん一行ごとに行われている。一行ずつ進みながら複数行を対象に検索を行ってるってわけ。無駄だし目に見えて遅い。 * バッファ長の制限により、マッチ範囲が途中で切られたりマッチの探索が打ち切られたりしても何も言わないのをなんとか。(制限をなくすかメッセージでも) *「[[SourceForge.net: Sakura Editor: Detail: 2309002 - 正規表現による複数行検索対応(簡易版)|http://sourceforge.net/tracker/?func=detail&aid=2309002&group_id=12488&atid=1013762]]」のコメントを見ると、検索語ハイライトのほかに「すべて置換」にもパッチが必要そう。パッチを流し読みしてたら BookmarkManager(::MarkSearchWord)までが GrepAgentが持ってたような検索の勝手実装を持ってるらし。SearchAgentを使ってよね。 *(複数行)検索にマッチしたなかでも、最初の行がマッチに含まれているか含まれていないかというのは区別する価値がある。サクラエディタの既存の実装は行指向が強いだろうから、「マッチした(ただし先のほうの行で)」ということを勘違いしかねない。(SearchAgentや選択範囲にはそういう指向がないから運良く複数行検索が自然に実装できただけ)