- ベストアンサー
正規表現での検出箇所調査について
- C言語版の鬼車ライブラリを利用して、正規表現を使用した検索プログラムを作成しています。しかし、特定のパターンを指定して検出箇所を調べる際に問題が発生しています。
- onig_search()を使用して特定のパターンに一致する全ての検出箇所を調べたいのですが、最初の1件しか検出されません。
- 問題が解決せず困っており、どなたか解決策をご存知の方がいらっしゃいましたら、お知恵を貸していただけないでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#1/3です。少々訂正。 > startを前回のヒット位置(onig_searchの戻り値)+strへずらしながら startを前回のヒット位置(onig_searchの戻り値) + str 「+ strlen(pattern)」へずらしながら です。でないと無限ループしてしまいますね。
その他の回答 (3)
- D-Matsu
- ベストアンサー率45% (1080/2394)
#1です。 改めて仕様を読み直してみたら、戻り値が最初のヒット位置というだけで、それとは別に引数の構造体regionにヒット数と開始・終了アドレスが入るんですね。 読み違えてました。失礼。 さて、それを踏まえて例示されたコードですが、間違いはなさそうに見えます。 こちらでも以下の環境下で試してみたのですが、 ・OpenSuSE 11.4 x64 ・gcc 4.5.1 配布元の最小限使用例に対してonig_newのencをUTF8に変えてpatternとstrを質問と同じ状態にしてみただけのコードで再現しますね……。 ASCIIに直して追試したらUTF-8と同じ結果が出たので、なんとなくですがUTF-8の処理が甘いような印象があります。 「とりあえず回避」というやり方ですが、startを前回のヒット位置(onig_searchの戻り値)+strへずらしながらヒットしなくなるまで一つずつ拾っていく手かと思います。
- Tacosan
- ベストアンサー率23% (3656/15482)
#1 で書かれているように onig_search が 「start⇒rangeの間で最初にマッチした部分」を返す というなら, それは「あなたが思っていた動作」に対して適切なコードではないと思われますが.... region の情報を使ってループ?
- D-Matsu
- ベストアンサー率45% (1080/2394)
まず「どう呼んでいるか」を提示してもらわないことにはどこが誤ってるのかも指摘しようがないんですが…… API仕様を読んだ感じでは「start⇒rangeの間で最初にマッチした部分」を返すようなので、「意図に合うような呼び出し方をしていない」線が濃厚じゃないかという気はするのですが。
補足
D-Matsuさん 回答ありがとうございます。 >まず「どう呼んでいるか」を~ ごもっともです。 コメント用に少し簡易的に編集していますが、 概ねこんな感じです。 ※ --ココカラ-- unsigned char *start, *range, *end; // 正規表現用ポインタ regex_t* reg = NULL; // 正規表現オブジェクト OnigErrorInfo eInfo; char *Target = "最初の試験、二番目の試験、三番目の試験、最後の試験"; char *pattern = "試験"; onig_new(®, (unsigned char*)pattern, (unsigned char*)pattern + strlen((char*)pattern), ONIG_OPTION_MULTILINE | ONIG_OPTION_IGNORECASE, ONIG_ENCODING_UTF8, ONIG_SYNTAX_DEFAULT, &eInfo); end = (unsigned char*) (Target + strlen((char*)Target)); start = (unsigned char*) pTarget; range = end; region = onig_region_new(); onig_search(reg, Target, end, start, range, region, ONIG_OPTION_NONE); --ココまで-- で、onig_search()の結果として、構造体regionに格納されるのですが、 該当数を示すregion->num_regs は1 になっており、初回該当の情報のみ格納されています。 確認した感じでは意図通りの呼び方に見えたのですが、 期待値と異なります。。。 どうでしょうか?
お礼
D-Matsu さん 回答ありがとうございます。 > 改めて仕様を読み直してみたら、戻り値が最初のヒット位置というだけで、それとは別に引数の構造体regionにヒット数と開始・終了アドレスが入るんですね。 > 読み違えてました。失礼。 確認ありがとうございます。 > さて、それを踏まえて例示されたコードですが、間違いはなさそうに見えます。 > こちらでも以下の環境下で試してみたのですが、 > > ・OpenSuSE 11.4 x64 > ・gcc 4.5.1 > > 配布元の最小限使用例に対してonig_newのencをUTF8に変えてpatternとstrを質問と同じ状態にしてみただけのコードで再現しますね……。 > ASCIIに直して追試したらUTF-8と同じ結果が出たので、なんとなくですがUTF-8の処理が甘いような印象があります。 > > 「とりあえず回避」というやり方ですが、startを前回のヒット位置(onig_searchの戻り値)+strへずらしながらヒットしなくなるまで一つずつ拾っていく手かと思います。 すいません。再現確認までして頂いて感謝します。 そうですよね。。。 私もこの方法しかないと考えていました。 入力情報(検索対象とパターン)はファイルから読み込む設定値なので、プログラムを変えずに対応できれば と思っていたのですが。。。了解です。 当初、鬼車ライブラリの使用方法の誤りかと思っていのたですが、 そうでもなさそうですね。 深夜に対応ありがとうございました。