FindRegular関数の動作が不安定No.08074
白雲斎 さん 05/06/08 07:04
 
Windows XP SP1, 秀丸 5.00 β27

再現性が特定しないので心許ない投稿ですが、取り合えず報告します。
末尾のマクロで、
    ・検索キーワードにマッチしない
    ・マッチするが、桁位置が異なる
    ・予期したとおりの結果になる
と言う、ばらついた実行結果になることがあります。
発生する頻度は『超極々まれに』で、エラー・メッセージ等はありません。
予期しない結果の場合でも、以下の流れで編集・実行すると、

     1. 検索キーワードの「英単語の始まり」(\<)を削除する。
        $p = "class *= *(\"|')?[^ \"'>]+(\"|')?";
     2. 予期したとおりの結果になる
     3. 検索キーワードの「英単語の始まり」(\<)を書き戻す。
        $p = "\\<class *= *(\"|')?[^ \"'>]+(\"|')?";
     4. 予期したとおりの結果になる

と不思議な現象が起こります。
サブルーチン製作途中の実験で指定した検索パターンに、たまたま「英単語の始
まり」を含めたと言うだけで、「英単語の始まり」が何か関係しているのかどう
かは分かりません。

検証し難い事案ではあると思いますが、よろしくお願いします。


※予期する結果(メッセージ):
 <blockquote class='new' title='sample'>
---------------------------------------------------------------
$s = "<blockquote class ='style' title='sample'>";
$p = "\\<class *= *(\"|')?[^ \"'>]+(\"|')?";
$re = "class='new'";

call SubStr $s, $p, $re;
if( ##return == -1 ) message "マッチしませんでした。";
else if( ##return == -2 ) message "不正な正規表現!";
else message $subStr;
endmacro;

// $$1 = 対象文字列, $$2 = 検索, $$3 = 置換
// 戻り値は、FindRegular の戻り値そのもの
// 置き換え後の文字列は、$subStr に格納
SubStr:
    loaddll "HmJre.dll";
    if( !result )
    {
        message "DLLロードに失敗!";
        endmacro;
    }
    ##m = dllfunc("FindRegularNoCaseSense", $$2, $$1, 0);
    if( ##m >= 0 )
    {
        ##sln = strlen($$1);
        ##mln = dllfunc( "GetLastMatchLength" );
        if( ##m )
        {
            ##i = ##sln - ##m - ##mln;
            if(##i) $subStr = leftstr($$1, ##m) + $$3 + rightstr($$1, ##i);
            else $subStr = leftstr($$1, ##m) + $$3;
        }
        else
        {
            $subStr = $$3 + rightstr($$1, ##sln - ##mln);
        }
    }
    freedll;
return ##m;
---------------------------------------------------------------


[ ]
RE:08074 FindRegular関数の動作が不安定No.08075
秀まるお さん 05/06/08 08:49
 
 いろいろ面倒なバグ出してばかりですみません。

 正規表現パターンを変更したら復旧するというのは大いにヒントになります。
というのは、実はFindRegular等の関数では、直前の正規表現パターンと同じな
ら、いわゆる「コンパイル」って処理を省略するようなことをしていますので、
それが関係してる可能性が高いです。

 とにかくいろいろテストしてみます。

[ ]
RE:08075 FindRegular関数の動作が不安定No.08077
秀まるお さん 05/06/08 09:36
 
 前回のバグと同じパターンでダメでした。つまり、一度エラーになるような正
規表現パターンを発生させると、以後おかしくなるようです。

 1.普通にマクロ実行  --> OK
 2.マクロの正規表現パターン部分をいじって意図的に「不正な正規表現!」
   メッセージを発生させる。
 3.マクロを元に戻して実行 --> 「マッチしませんでした。」

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

[ ]
RE:08077 FindRegular関数の動作が不安定No.08137
白雲斎 さん 05/06/10 16:09
 
β28で検証しましたが、先の投稿と同じく、ばらついた実行結果になります。

あれこれ編集・実行を繰り返したので、手順等は覚えていませんが、

$s = "<blockquote class ='style' title='sample'>";
$p = "\\<class *= *(\"|')?[^ \"'>]+(\"|')?";

文字列の class を xclass にする => マッチする「おかしい!」
パターンの括弧をどれか削除する  => 不正な正規表現
括弧を書き戻す                  => マッチしない

など

[ ]
RE:08137 FindRegular関数の動作が不安定No.08139
秀まるお さん 05/06/10 17:03
 
 一応、前回もいろいろいじってテストしたり今またテストしたりもしてみたん
ですけど、いまいち正常動作してるような気がします。

 もうちょっとテストしてみますけど、もしかしてこのマクロとは別に
FindRegularする文を含んだマクロなんかも実行してますかね?。だとすると、
それによる複合的な原因かもしれませんけど。

[ ]
RE:08139 FindRegular関数の動作が不安定No.08141
白雲斎 さん 05/06/10 17:37
 
検証したのは、このスレッド頭で投稿したマクロそのものです。
マクロ先頭の2つの変数のみを編集して実行しています。

また、FindRegular関数は、このマクロ以外では使用していません。
と言うか、使えません。

う〜ん、この症状の報告者が私だけというのが気になります・・・。

[ ]
RE:08141 FindRegular関数の動作が不安定No.08145
bouz さん 05/06/10 18:26
 
ボクもそれぞれ100回ずつ計300回実行しましたが、想定通り動きました。
古いhmjre.dllがどっかにある?

[ ]
RE:08145 FindRegular関数の動作が不安定No.08149
白雲斎 さん 05/06/10 20:18
 
わざわざの検証とコメントありがとうございます。

> 想定通り動きました。
そうですか、う〜ん、なぜだろう!?

正規表現パターンが
「正しい」、「不正」、「前回と同じ」、「前回と違う」
の組み合わせによって、症状が出る/出ないが起こっているような印象なんです
よね。
あまり、秀まるお氏に負担のかかることはしたくないのですが、さりとて放って
おくのも何だし・・・。

[ ]
RE:08145 FindRegular関数の動作が不安定No.08151
白雲斎 さん 05/06/10 20:52
 
>古いhmjre.dllがどっかにある?

鶴亀、PDIC(Personal Dictionary)のプログラム・ディレクトリにはありますが、
systemなどのパスの通った所にはありません。

[ ]
RE:08151 FindRegular関数の動作が不安定No.08152
秀まるお さん 05/06/10 21:22
 
 β27時点ではたしかにHmJre.dllにバグがあったんですけど…。

 とりあえず再現テストするのも大変なので、次のHmJre.dllにて、コンパイル
を省略して高速化する処理をやめて、とにかくFindRegular関数が呼ばれたら毎
回コンパイルするって方式にしてみます。

 (ここで言う「コンパイル」とは、正規表現パターンを内部的な形式に変換す
る処理のことです)

 それでまたテストの程お願いします。

 それでもし直るなら、とりあえずFindRegular/FindRegularNoCase関数はその
ような「毎回コンパイル」って風にしつつ、それとは別に、

    #handle = dllfunc("CompileRegular", $pattern );
    #x = dllfunc("FindRegularFast", #handle, $target, #xStart );
    ...
    ...
    #tmp = dllfunc("FreeCompiledData", #handle );

 みたいな方式の関数を用意しようかと思います。

[ ]
RE:08149 FindRegular関数の動作が不安定No.08153
bouz さん 05/06/10 21:35
 
>わざわざの検証とコメントありがとうございます。
あ、いえいえただの酔狂人ですから。
最終的にはこんな風にして、500回、1000回やってみましたが、
結果は予想通りです。
$s[0] = "<blockquote xclass ='style' title='sample'>";
$s[1] = "<blockquote class ='style' title='sample'>";
$s[2] = "<blockquote class ='style' title='sample'>";
$p[0] = "\\<class *= *(\"|')?[^ \"'>]+(\"|'?";
$p[1] = "\\<class *= *(\"|')?[^ \"'>]+(\"|')?";
$re = "class='new'";
#n = 0;
while (#n<=500) {
 call SubStr $s[#n%3], $p[#n%2], $re;
 #n = #n +1;
}
if( ##return == -1 ) message "マッチしませんでした。";
else if( ##return == -2 ) message "不正な正規表現!";
else message $subStr;
endmacro;

500のところを501とか502とかやって実行する。

[ ]