あいまい検索 その6No.28578
rosegardenyk さん 10/07/07 00:52
 
こんにちわ,rosegardenです.

"FindGeneral" であいまい検索指定をし、極めて特殊な場合におこる問題です。
dllfunc( "FindGeneral", 0, 1, 1, $S2, $S1, 0); //正規表現+あいまい検索
2回目の開始位置を一度ヒットした文字列のすぐ後ろに指定した時に発見しました。
下記のとおり、再現は容易ですが、どういう場合に問題がおきるのかは不明です。ど
う対処したらよいでしょうか。

V8.01 β10 (hmjre.dll V3.22)
////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////
loaddll "hmjre.dll";
//例 1-1 (正常) 検索開始位置(0), ヒット位置(158)
$S1 = "「第一選択の」「ドパミン」「と」「ノルエピネフリン」は,いずれも有効性が評価
されており,「ショックの治療」における「第一選択の」「ノルエピネフリン」「と」「ドパ
ミン」はどちらも「昇圧薬」として「推奨」されることとした.";

$S2 = "(「.+?」)+として";
   ##prev = 0;
   while (1) {
    ##d = dllfunc( "FindGeneral", 0, 1, 1, $S2, $S1, 0);
question "例 1-1 (正常) 「いいえ」で break" + "\n##d = " + str(##d) + "\n$S2
= " + $S2 + "\n$S1 = " + $S1; if (!result) break;
    if (##d < 0) break;
    }
//例 1-2 (異常) 検索開始位置を本来ヒットする位置(158)より後方(172)セットして
も ヒットし、その結果ループする例)
$S1 = "「第一選択の」「ドパミン」「と」「ノルエピネフリン」は,いずれも有効性が評価
されており,「ショックの治療」における「第一選択の」「ノルエピネフリン」「と」「ドパ
ミン」はどちらも「昇圧薬」として「推奨」されることとした.";

$S2 = "(「.+?」)+として";
   ##prev = 0;
   while (1) {
    ##d = dllfunc( "FindGeneral", 0, 1, 1, $S2, $S1, 172);
question "例 1-2(異常) 「いいえ」で break" + "\n##d = " + str(##d) + "\n$S2=
 " + $S2 + "\n$S1 = " + $S1; if (!result) break;
    if (##d < 0) break;
    }
//例 2 (正常)  「第一選択の」 ⇒ 第一選択の」   例1に対し最初の1文字"「"を削除し
ただけです.
$S1 = "第一選択の」「ドパミン」「と」「ノルエピネフリン」は,いずれも有効性が評価さ
れており,「ショックの治療」における「第一選択の」「ノルエピネフリン」「と」「ドパミ
ン」はどちらも「昇圧薬」として「推奨」されることとした.";

##i = 1;
$S2 = "(「.+?」)+として";
   ##prev = 0;
   while (1) {
    ##d = dllfunc( "FindGeneral", 0, 1, 0, $S2, $S1, 172);
question "例 2 (正常)「はい」/「いいえ」どちらでもbreak" + "\n##d = " + str
(##d) + "\n$S2= " + $S2 + "\n$S1 = " + $S1; if (!result) break;

    if (##d < 0) break;
    }

//例 3 (正常)  例1に対し、文字列$S1は同じで、あいまい検索Flagを 1 ⇒ 0 に変
更しただけ
$S1 = "「第一選択の」「ドパミン」「と」「ノルエピネフリン」は,いずれも有効性が評価
されており,「ショックの治療」における「第一選択の」「ノルエピネフリン」「と」「ドパ
ミン」はどちらも「昇圧薬」として「推奨」されることとした.";

$S2 = "(「.+?」)+として";
   ##prev = 0;
   while (1) {
    ##d = dllfunc( "FindGeneral", 0, 1, 0, $S2, $S1, 172);
question "例 3 (正常) 「はい」/「いいえ」どちらでもbreak" + "\n##d = " + str
(##d) + "\n$S2= " + $S2 + "\n$S1 = " + $S1; if (!result) break;
    if (##d < 0) break;
    }

endmacro;

[ ]
RE:28578 あいまい検索 その6No.28580
秀まるお2 さん 10/07/07 09:28
 
 連絡いただいたマクロではいまいちおかしい現象が起きないような貴がします
けども、検索対象文字列に半角カナを入れたマクロの例を作ってみたら、一応現
象が確認出来ました。

 例えばですけども、以下のマクロの中で、「カ」と書いてる部分は実は半角の
カナだとします。

    loaddll "hmjre.dll";
    #n = dllfunc("FindGeneral", 1, 1, 1, "あ", "カカカあ", 0 );
    message str(#n);

 とやると、「3」が表示されます。これは正しいですが、検索開始位置として
「4」を指定した場合、ヒットしないはずですが、

    loaddll "hmjre.dll";
    #n = dllfunc("FindGeneral", 1, 1, 1, "あ", "カカカあ", 4 );
    message str(#n);

 とすると、なぜかヒットした位置として「4」が表示されてしまいます。

 ということで、そういうバグがあることは間違いないと思います。

 あいまい検索がONの時は、検索文字列や検索対象文字列を変換することになる
ので、検索開始位置もそれなりの変換が必要になるんですが、その変換の処理が
抜けてるような気がします。

 ということで、さっそく修正させていただきます。

[ ]
RE:28580 あいまい検索 その6No.28582
秀まるお2 さん 10/07/07 11:18
 
 rosegardenさんの発言にあるカタカナ文字列は、実は本当は半角なのですね。
(でないとヒット位置が158にならないので)

 ここの会議室は半角カナが全角に変換されてしまうので、ちょっとその辺分か
りませんでした。

 そういうことで、僕の理解した現象と同じということで、次また修正させてい
ただきます。

 毎度お手数かけてすみません。

[ ]
RE:28582 あいまい検索 その6No.28583
rosegardenyk さん 10/07/07 12:43
 
> rosegardenさんの発言にあるカタカナ文字列は、実は本当は半角なのですね。
>(でないとヒット位置が158にならないので)
>

カタカナ文字列⇒正確にはカッコのみ半角カタカナです。
自作用語集で最長一致検出された結果を半角の「」ではさんでいます。

$S1 = "「第一選択の」「ドパミン」「と」「ノルエピネフリン」は,いずれも有効性が評価
されており,「ショックの治療」における「第一選択の」「ノルエピネフリン」「と」「ドパ
ミン」はどちらも「昇圧薬」として「推奨」されることとした.";

の例文は」「ドパミン」であればカッコは半角カタカナのカッコ"「"(0xA2)と"」"(0xA3)
でドは全角カタカナ(0x8368)です。 これで全角を2文字半角カッコ"「"や"」"を一文字
と数えて158となることを目で確認しています。
FindGeneralの戻り値とも一致します。

rosegarden

[ ]
RE:28580 あいまい検索 その6No.28584
colder さん 10/07/07 13:22
 
colderです

あいまい検索時におかしくなること以前の問題として、rosegardenyk さん
のマクロの例1-1でヒットする位置が158になるのは何故なんでしょうか?

ほかの正規表現で似たような検索をさせると、ヒットする位置は0になります。


[ ]
RE:28584 あいまい検索 その6No.28585
秀まるお2 さん 10/07/07 13:31
 
 実はここのコミュニテックスの会議室は、書き込み方法にもよるんですが、半
角カナを書き込んでも全角に変換されてしまうケースが多いです。

 元のデータ的には半角カナが多数あるということで、それでヒットする位置が
158になるようです。

 具体的な半角文字の位置は別として、とりあえず同じような再現が出来たので、
修正出来たと思います。

[ ]
RE:28583 あいまい検索 その6No.28586
秀まるお2 さん 10/07/07 13:32
 
 一応、同じ状況で再現が出来たので、次のバージョンで直ると思います。とい
うことでお願いします。

[ ]
RE:28585 あいまい検索 その6No.28587
colder さん 10/07/07 14:46
 
そういうことではなくて、
ヒットする部分がほかの正規表現と違っています。

hmonig.dllとの違いがあることを示すマクロを以下に書いておきます

//ここから
$string = "<foo>hoge<bar>baz";
$search = "(<.+?>)+baz";

#hmjre=loaddll("hmjre.dll");
#a1 = dllfunc(#hmjre,"FindRegular", $search, $string, 0);
message "ヒットした位置は「"+str(#a1)+"」です";
freedll #hmjre;

#onig=loaddll("hmonig.dll");
#a2 = dllfunc(#onig, "FindRegular", $search, $string, 0);
message "ヒットした位置は「"+str(#a2)+"」です";
freedll #onig;
endmacro;

[ ]
RE:28587 あいまい検索 その6No.28588
秀まるお2 さん 10/07/07 15:08
 
 なんだかまた1つバグが見つかってしまったような気がします。

 意味的にはHmJre.dllの動作で合ってるような気がしたんですが、

   xxx<foo>hoge<bar>baz";

 という文字列に対して、正規表現で

   xxx(<.+?>)+baz

 とやった時に、うまくマッチしないようでした。

 これはバグのような気がします。

 もうちょっと詳しく調べてみます。

[ ]
RE:28588 あいまい検索 その6No.28591
秀まるお2 さん 10/07/08 09:53
 
 いろいろ調べてみたら、根本的なアルゴリズム的な所に問題があって、簡単に
は直せない感じになってきました。

 ちょっと時間がかかりそうです。

 それで、とりあえずrosegardenykさんから連絡いただいたFindGeneral関数の
バグ修正だけして、それでV3.23として一回秀丸エディタ/秀丸メールに添付さ
せていただく形にします。

 V3.24以降で直る予定ということでお願いします。

[ ]
RE:28586 開始位置の指定による異常の別例No.28595
rosegardenyk さん 10/07/08 13:05
 
あいまい検索ではありませんが、開始位置が 0 以外だと「の」にヒットしません。
エラーだとすると単純すぎるので、何か私の調べ方がおかしいですか? 例文に半角カ
タカナは使っていません。    
V8.01β10です。
問題ということであれば、FindRegularやReplaceRegularも調べていただけますか?

//// macro ///////////////////////////////////////////////
loaddll "hmjre.dll";

$$S1 = "〔ショック〕の〔治療〕";

$$t = dllfuncstr("ReplaceRegularNoCaseSense","^.*〕(.)〔.*$", $$S1, 0, "\\1"
 , 0);
message "Case 1 〕" + $$t + "〔";

$$t = dllfuncstr("ReplaceRegularNoCaseSense","^.*〕(.)〔.*$", $$S1, 1, "\\1"
 , 0);
message "Case 2 〕" + $$t + "〔";
//////////////////////////////////////////////////////////

[ ]
RE:28595 開始位置の指定による異常の別例No.28596
秀まるお2 さん 10/07/08 15:10
 
 検索文字列の先頭に「^」があるのですが、これは行頭にしかマッチしないの
で、検索開始位置が1以上だとヒットしないというのは、それはそれで仕様通り
だと思います。

[ ]
RE:28596 開始位置の指定による異常の別例No.28597
rosegardenyk さん 10/07/08 16:35
 
>で、検索開始位置が1以上だとヒットしないというのは、それはそれで仕様通り>だ
>と思います。
了解です。

[ ]