HmJre.dll でのあいまい検索についてNo.38188
black さん 20/05/08 00:00
 
いつもお世話になっております。

Jre2GetMatchInfo_V318 を利用して「あいまい検索」を行うとクラッシュしてしまう
のですが、どんな問題が考えられるかご教授いただきたいです。

なお、こちらのフォーラムは参照しました。
https://www.maruo.co.jp/hidesoft/2/x38102_.html?a=2


【コード】
初期化は省略...

JREFUZZYDATA data;
data.dwSize = sizeof(JREFUZZYDATA);
int ret = Fuzzy_Open(&data, false);
if (!ret) {
   ::puts("error Fuzzy_Open");
   return 1;
}

// 検索用の正規表現をコンバート
ret = Fuzzy_ConvertFindString(&data, find, 1);
if (!ret)return false;
char* findConverted;
findConverted = data.pszFindConved;

// 検索対象をコンバート
ret = Fuzzy_ConvertTarget(&data, input);
if (!ret) {
   ::puts("error Fuzzy_ConvertTarget");
   return 1;
}

// jre2 open
JRE2 jre;
jre.dwSize = sizeof(JRE2);
ret = Jre2Open(&jre);
if (!ret) {
   ::puts("errror Jre2Open");
   return 1;
}

// jre2 compile
ret = Jre2Compile(&jre, findConverted.GetString());
if (!ret) {
   ::puts("errror Jre2Compile");
   return 1;
}

jre.nStart = 0;
// 以下の関数を呼び出すと「0x00000000 で例外がスローされました」と表示されます
ret = Jre2GetMatchInfo_V318(&jre, data.pszTargetConved, data.cchTargetConved,
 FALSE, NULL);
if (!ret) {
 ::puts("not found __Jre2GetMatchInfo_V318");
}

【経緯】
・元々は Jre2GetMatchInfo_HmJre を利用していたのですが「あいまい検索」で期待
した検索結果にならなかったので利用する関数を変更しました。「あいまい検索」以
外は問題なく動作しています。

【利用環境】
・HmJre.dll 5.0.6.0
・JreFuzzy.h 2018/8/26版
・Visual Studio 2017

[ ]
RE:38188 HmJre.dll でのあいまい検索につNo.38192
秀まるお2 さん 20/05/08 09:51
 
 保護違反が発生する理由ですが、Jre2GetMatchInfo_V318に渡す第5パラメーター
がNULLのせいってことになります。

    ret = pfnJreGetMatchInfo_V318(&jre, data.pszTargetConved, data.cchTarget
Conved, FALSE, &data);

 のように&dataを渡せば大丈夫です。

 ちなみにこちらでテストした例としては以下のようになります。

    JREFUZZYDATA data;
    data.dwSize = sizeof(JREFUZZYDATA);
    int ret = Fuzzy_Open(&data, false);
    if (!ret) {
       return 1;
    }
    char*   find = "test";
    char*   input = "aaaaa_test_aaaaa";

    // 検索用の正規表現をコンバート
    ret = Fuzzy_ConvertFindString(&data, find, 1);
    if (!ret)return false;
    char* findConverted;
    findConverted = data.pszFindConved;

    // 検索対象をコンバート
    ret = Fuzzy_ConvertTarget(&data, input);
    if (!ret) {
       return 1;
    }

    // jre2 open
    JRE2 jre;
    jre.dwSize = sizeof(JRE2);
    ret = Jre2Open(&jre);
    if (!ret) {
       return 1;
    }

    // jre2 compile
    ret = Jre2Compile(&jre, findConverted);
    if (!ret) {
       return 1;
    }

    jre.nStart = 0;
    // 以下の関数を呼び出すと「0x00000000 で例外がスローされました」と表示さ
れます
    ret = Jre2GetMatchInfo_V318(&jre, data.pszTargetConved, data.cchTargetCo
nved, FALSE, &data);
    if (!ret) {
        return 1;
    }
    return 0;

[ ]
RE:38192 HmJre.dll でのあいまい検索につNo.38195
black さん 20/05/08 15:38
 
ご返信ありがとうございます。動作できました。

ただ改めて「期待していた動作と異なっているため」引き続き確認させてください。

【確認内容】
今回テストデータとして以下を渡しております。

 char* find  = "api.*";  // 正規表現
 char* input = "TEST_aPsSS_26"; // 検索対象データ

これは "TEST_aPsSS_26" という文字列から、大文字小文字を無視して "api.*" が見
つかった時、ヒットすることを期待しています。

現行の動作をさせると、"api" や "API" などの文字列がないのに Jre2GetMatchInfo
_V318 の戻り値で 1 が返却され「見つかった」と判断されています

ret = Jre2GetMatchInfo_V318(&jre, data.pszTargetConved, data.cchTargetConved,
 FALSE, &data);

printf("ret: %d\n", ret);
printf("nPosition: %d\n", jre.nPosition);
printf("nLength: %d\n", jre.nLength);

>>出力結果
>> ret: 1
>> nPosition: 5
>> nLength: 8

Jre2GetMatchInfo_V318 の戻り値は「見つからない」を期待していたのですが、なぜ
このようになるのでしょうか。
 

【補足】
あいまい検索を行う場合、flags に下記のオプションがあるのは把握しております。

// JreFuzzy.h
#define FUZZYOPTION_NOCASE    1  // 半角英数字の大文字/小文字を区別しない
//廃止#define FUZZYOPTION_NOCASEZENKAKU  2  // 全角英数字の大文字/小文字を
区別しない
#define FUZZYOPTION_NOHANZEN   4  // 半角/全角を区別しない
#define FUZZYOPTION_NOHIRAKATA   8  // ひらがなとカタカナを区別しない
#define FUZZYOPTION_NOBIGSMALLKANA  0x10 // 大きい「あ」と小さい「ぁ」を区別
しない
#define FUZZYOPTION_NODAKUON   0x20 // 濁音、半濁音を区別しない。「は」、
「ば」、「ぱ」を同一視する。
#define FUZZYOPTION_KANAHYPHEN   0x40 // かなの「ー」と英数の「−」を同一視する
#define FUZZYOPTION_NOSPACE    0x80 // 空白/タブ文字を無視する
#define FUZZYOPTION_NORETURN   0x100 // 改行を無視する
#define FUZZYOPTION_CUSTOMIGNORE  0x200 // 特定文字を無視する。V1.09から。
#define FUZZYOPTION_NOBREAKSPACE  0x400 // V1.88 2007.11.01 No-Break Space
(ユニコードで0xA0)を半角空白と同一視する。


よろしくお願いいたします。

[ ]
RE:38195 HmJre.dll でのあいまい検索につNo.38198
秀まるお2 さん 20/05/08 17:01
 
 こちらでテストした限りでは、

>  char* find  = "api.*";  // 正規表現
>  char* input = "TEST_aPsSS_26"; // 検索対象データ

 ではヒットしませんでしたけども、どうしてこういう違いが起きるのやら?

 そもそも的に、大文字小文字の区別をしないとしても、"api"って文字列にヒット
することは無いはずのような気がします。

 サンプルプログラムを完全な形でここに書き込んでいただければ、それをそのまま
コンパイル&トレースして僕の方でテストすることは出来ます。

 ちなみに僕の作ったサンプルは、以下のようになります。HmJre.dllの関数呼び出
しが「pfnXXXX」のようになってるのは、LoadLibraryして呼び出してる関係ですけど
も。


----------------------------------------------------------------------------
int TestJre() {
    JREFUZZYDATA data;
    data.dwSize = sizeof(JREFUZZYDATA);
    int ret = pfnFuzzy_Open(&data, false);
    if (!ret) {
       return 1;
    }
    char* find  = "api.*";  // 正規表現
    char* input = "TEST_aPsSS_26"; // 検索対象データ

    // 検索用の正規表現をコンバート
    ret = pfnFuzzy_ConvertFindString(&data, find, 1);
    if (!ret)return false;
    char* findConverted;
    findConverted = data.pszFindConved;

    // 検索対象をコンバート
    ret = pfnFuzzy_ConvertTarget(&data, input);
    if (!ret) {
       return 1;
    }

    // jre2 open
    JRE2 jre;
    jre.dwSize = sizeof(JRE2);
    ret = pfnJreOpen(&jre);
    if (!ret) {
       return 1;
    }

    // jre2 compile
    ret = pfnJreCompile(&jre, findConverted);
    if (!ret) {
       return 1;
    }

    jre.nStart = 0;
    // 以下の関数を呼び出すと「0x00000000 で例外がスローされました」と表示さ
れます
    ret = pfnJreGetMatchInfo_V318(&jre, data.pszTargetConved, data.cchTarget
Conved, FALSE, &data);
    if (!ret) {
        return 1;
    }
    return 0;
}
----------------------------------------------------------------------------

 テストすると、pfnJreGetMatchInfo_V318からは0が返りました。

 data.flags = 0; とか書き込んでいただくと、たしかにヒットしなくなるかもしれ
ません。一回それをテストしてもらう手もあります。

[ ]
RE:38198 HmJre.dll でのあいまい検索につNo.38199
秀まるお2 さん 20/05/08 17:27
 
 一応追加ですが、

    char* find  = "aps.*";  // 正規表現
    char* input = "TEST_apsSS_26"; // 検索対象データ

 とした場合にはうまくヒットして、

   nPosition: 5
   nLength: 8

 となりました。

[ ]
RE:38199 HmJre.dll でのあいまい検索につNo.38200
black さん 20/05/08 18:05
 
頂いたコードをそのまま再現しましたが、やはり...ヒットしてまう状況でした。

下記2つの関数に関しては明示的に "2" の関数を利用しています。
>> pfnJreOpen  => Jre2Open
>> pfnJreCompile => Jre2Compile

【補足】
・flags を 0 にした場合は、期待通りに「ヒットしない」という状況でした。


【再現コード】
int TestJre() {
 JREFUZZYDATA data;
 data.dwSize = sizeof(JREFUZZYDATA);
 int ret = Fuzzy_Open(&data, false);
 if (!ret) {
  return 1;
 }
 // data.flags = 0; // 0にすると期待通り not found となる

 char* find = "api.*";     // 正規表現
 char* input = "TEST_aPsSS_26"; // 検索対象データ

 // 検索用の正規表現をコンバート
 ret = Fuzzy_ConvertFindString(&data, find, 1);
 if (!ret)return false;
 char* findConverted;
 findConverted = data.pszFindConved;

 // 検索対象をコンバート
 ret = Fuzzy_ConvertTarget(&data, input);
 if (!ret) {
  return 1;
 }

 // jre2 open
 JRE2 jre;
 jre.dwSize = sizeof(JRE2);
 ret = Jre2Open(&jre);
 if (!ret) {
  return 1;
 }

 // jre2 compile
 ret = Jre2Compile(&jre, findConverted);
 if (!ret) {
  return 1;
 }

 jre.nStart = 0;
 // 以下の関数を呼び出すと「0x00000000 で例外がスローされました」と表示されます
 ret = pfnJre2GetMatchInfo_V318(&jre, data.pszTargetConved, data.cchTargetCo
nved, FALSE, &data);
 if (!ret) {
  return 1;
 }
 puts("hit");
 return 0;
}


【改めての利用環境】
・HmJre.dll 5.0.6.0
・JreFuzzy.h 2018/8/26版
・Visual Studio 2017
・LoadLibrary を使用しての検証


[ ]
RE:38200 HmJre.dll でのあいまい検索につNo.38201
秀まるお2 さん 20/05/08 18:44
 
> 【補足】
> ・flags を 0 にした場合は、期待通りに「ヒットしない」という状況でした。

 ならば、カスタム同一視指定か「類似検索」かどっちかの影響じゃないかという気
がします。

 試しに類似検索ON、類似度合い=2/3(66%)、ミスの上限=3にしたらヒットしました
けども。普通に秀丸エディタの検索ダイアログでテストできると思います。

 類似検索とカスタム同一視指定をOFFにして、大文字/小文字区別なしでテストする
例も書いてみます。一応これだとヒットしません。

int TestJre() {
    JREFUZZYDATA data;
    data.dwSize = sizeof(JREFUZZYDATA);
    int ret = pfnFuzzy_Open(&data, false);
    if (!ret) {
       return 1;
    }
    data.flags |= FUZZYOPTION_NOCASE;       //大文字/小文字を区別しない
    data.flags &= ~(FUZZYOPTION_SIMILAR|FUZZYOPTION_CUSTOM1|FUZZYOPTION_CUST
OM2|FUZZYOPTION_CUSTOM3|FUZZYOPTION_CUSTOM4);
                                            //類似検索、カスタム同一視指定な
し。

    char* find = "api.*";     // 正規表現
    char* input = "TEST_aPsSS_26"; // 検索対象データ

    ...
    ...

[ ]
RE:38201 HmJre.dll でのあいまい検索につNo.38202
black さん 20/05/08 20:33
 
ご確認ありがとうございます。
無事、頂いたコードで期待通りに動作しました。

>>カスタム同一視指定
>>類似検索
上記の用語については理解しておりませんでした。
以下をご参考にさせていただきます。
https://help.maruo.co.jp/hmjre/html/0001_IDH_FUZZYDIALOG.html


2点ほどご質問させてください。

【1つ目】
あいまい検索オプションの 「flags のデフォルト値」は HmJre.dll のバージョンに
よって変わるという認識で良いでしょうか?

【2つ目】
>>類似度合い=2/3(66%)、ミスの上限=3
プログラムコードで、上記のように具体的な数字を指定することはできるのでしょう
か?

flags で「有効にする/無効にする」はできるかと思うのですが、
具体的にミスの上限を増やしたい(減らしたい)と言った場合、指定の仕方を理解し
ておりません。


よろしくお願いいたします。

[ ]
RE:38202 HmJre.dll でのあいまい検索につNo.38204
秀まるお2 さん 20/05/09 17:44
 
> あいまい検索オプションの 「flags のデフォルト値」は HmJre.dll のバージョン
>によって変わるという認識で良いでしょうか?

 HmJre.dllのバージョンで変わることは無くて、単純に秀丸エディタや秀丸メール
にて、あいまい検索の設定をした通りになる、という感じです。

 秀丸エディタの検索ダイアログの「あいまい検索」オプションの右側のボタンで設
定したのが初期値として設定されます。

> >>類似度合い=2/3(66%)、ミスの上限=3
> プログラムコードで、上記のように具体的な数字を指定することはできるのでしょ
>うか?

 JreFuzzy.hの中にある、

#define FUZZYOPTION_SIMILARPERCENT_MASK 0x06000000 //V5.00 2ビット
#define FUZZYOPTION_SIMILARPERCENT_SHIFT 25  //V5.00

 の2ビットにてパーセントを指定して、

#define FUZZYOPTION_SIMILARLIMIT_MASK 0x00C00000 //V5.00 2ビット。1〜4
#define FUZZYOPTION_SIMILARLIMIT_SHIFT 22   //V5.00

 の2ビットにして上限を指定する形になります。

 パーセントについては、

 2/3 (66%)  ... 0
 3/4 (75%)  ... 1
 4/5 (80%)  ... 2

 って値になるんですが、その値(nSimilarLevelと表す)を、

    flags &= ~FUZZYOPTION_SIMILARPERCENT_MASK;
    flags |= nSimilarLevel << FUZZYOPTION_SIMILARPERCENT_SHIFT

 みたいにしてセットします。

 ミスの上限については、

 1
 2
 3
 4

 の4種類に値について、以下の変換をしてセットします。

    nLimit = (nLimit - 3 + 4) % 4;
    flags &= FUZZYOPTION_SIMILARLIMIT_MASK;
    flags |= nLimit << FUZZYOPTION_SIMILARLIMIT_SHIFT;

 ちょっとヘルプの説明が間違ってますけども・・・。

 こんな感じで大丈夫なはずです。

[ ]
RE:38204 HmJre.dll でのあいまい検索につNo.38205
black さん 20/05/10 12:14
 
ありがとうございます。
頂いた情報を元に試してみようと思います。

最後に一点だけ確認させてください。

>>flags のデフォルト値」は HmJre.dll のバージョンによって変わるという認識で
>良いでしょうか?
> HmJre.dllのバージョンで変わることは無くて、単純に秀丸エディタや秀丸メール
>にて、あいまい検索の設定をした通りになる、という感じです。
独自プログラムから呼び出す場合ですが、
今回 flags を特に指定しておらず「類似検索」でマッチしてしまった為...使わない
オプションは「明示的にオフにする」のが確実ですよね。

こちらのヘルプでは↓
https://help.maruo.co.jp/hmjre/html/0005_API_FUZZY.html
>>#define FUZZYOPTION_NOCASE  1 // 半角英数字の大文字/小文字を区別しない
>>JREFUZZYDATA構造体中のメンバーを呼び出し元が直接書き換えてはいけませんが、
>flagsメンバーのFUZZYOPTION_NOCASEビットだけは例外です。

とありましたが、今回頂いたコードでも「他のビット」をリセットされてますので、
上記内容は古いと判断しても宜しいでしょうか。

[ ]
RE:38205 HmJre.dll でのあいまい検索につNo.38206
秀まるお2 さん 20/05/11 09:05
 
> 今回 flags を特に指定しておらず「類似検索」でマッチしてしまった為...使わな
>いオプションは「明示的にオフにする」のが確実ですよね。

 オフにするというか、必要なフラグをONにして不要なフラグをOFFにするってした
方が確実かと思います。

> とありましたが、今回頂いたコードでも「他のビット」をリセットされてますので、
>上記内容は古いと判断しても宜しいでしょうか。

 かしかにヘルプにはフラグは書き換えるなと書いてるので、もしかしたら呼び出し
元で書き換えたらまずい事情があるのかもしれません。一回調べてみます。

 調べてみて、もしフラグ書き換えで問題がある場合はまたここにお返事させていた
だきます。問題ないようでしたらヘルプの方を修正させていただきます。

[ ]
RE:38206 HmJre.dll でのあいまい検索につNo.38208
black さん 20/05/11 16:18
 
> 調べてみて、もしフラグ書き換えで問題がある場合はまたここにお返事させてい
>ただきます。問題ないようでしたらヘルプの方を修正させていただきます。
承知しました。よろしくお願いいたします。

[ ]