SkRegExpW でのパイプ処理

解決


Terry  2024-08-11 12:46:33  No: 151547

いつもお世話になっています、Terry ですm(_ _)m

Gemini さんや Cursor さんとかいろいろな AI さん達とやりとりしたのですが解決しませんでした
内容は以下の通りです

諸事情のため、未だに Delphi2009+SkRegExpW での正規表現検索を使っています。
SkRegExpW は最新ソースも既に9年も前のもので現在のDelphiには正規表現が標準搭載されているので情報は少ないのですが
細々と手を加えながら使ってきました。
しかし今回根本的なアンマッチがあり途方に暮れています。
https://github.com/shukomiya/skregexp/tree/master/Demo/simple
にある最小限プロジェクトでも再現します。
正規表現「方法|手段|手口」
検索対象文字列「入手方法」
→「手方法」でヒット

Delphi11CE+System.RegularExpressions で作成したテストアプリや鬼車などを使った他のソフトでは正常に検索出来ます。

SkRegExpW のソースをひとつずつ追いかけてはみるのですが少し複雑すぎて追い切れません
https://github.com/shukomiya/skregexp/blob/master/SkRegExpW.pas
4262 行目の if FStartP = nil then で FStartP := '手方法' となったあたり?)

最終的に
正規表現 AB|CE
本文 CAB
でも「CAB」がヒットすることが判明しました

DEKOさんのサンプルコード https://ht-deko.com/tech064.html#0006_W
をお借りして最小限コードを書いてみましたがやはり「AAB」(一文字多い)がヒットします
uses SkRegularExpressions;

procedure TForm1.Button1Click(Sender: TObject);
const
  Exp = 'AB|BC';
var
  i: Integer;
  Collection: TMatchCollection;
  Dmy, mValue: String;
  mStart, mLength: Integer;
begin
  Memo2.Lines.Clear;
  Collection := TRegEx.Matches(Memo1.Lines.Text, Exp);
  for i:=0 to Collection.Count-1 do
    begin
      mValue  := Collection.Item[i].Value;
      mStart  := Collection.Item[i].Index;
      mLength := Collection.Item[i].Length;
      Dmy := Format('%s (%d, %d)', [mValue, mStart, mLength]);
      Memo2.Lines.Add(Dmy);
    end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Lines.Clear;
  with Memo1.Lines do
  begin
{    Add('ABCDEFG');
    Add('ABADDDAB');
    Add('DDABDDBC');}
    Add('AABCD');
  end;
end;

何かヒントがありましたらよろしくお願いします


AAAAA  2024-08-14 18:00:04  No: 151583

      //if FStartP = nil then 
        //FStartP := AStr;

      Inc(AStr, L);

      if Node.Accepted then
      begin
   //ここに移動
        if FStartP = nil then
          FStartP := AStr;

でどうかな?


Terry  2024-08-14 18:17:19  No: 151584

お返事ありがとうございます
上記の Button1Click で
mValue='', mStart=4, mLength=0
になってしまうようです


AAAAA  2024-08-14 19:39:29  No: 151585

      //if FStartP = nil then
      //  FStartP := AStr;
      if Node.IsHead then SAVE_ASTR := AStr;

      Inc(AStr, L);

      //if Node.Accepted then
      if (Node.Accepted) and (FMatchCount = 0) then
      begin

        if (FStartP = nil) then
        begin
          FStartP :=  SAVE_ASTR;
        end;

でどうかな? 
他の判定にどう影響するかはわからないけど


Terry  2024-08-14 23:04:34  No: 151586

何度もありがとうございます
以下の4通りですべて上手くマッチ出来ているようです

Regex:=TRegEx.Create(); ~Regex.Match()
RegExp:=TSkRegExp.Create; ~RegExp.Exec()
TSkRegExp.RegMatch('AB|BC','AABCD', SL)
TRegEx.Matches('AABCD', 'AB|BC');

明日が盆休み最終日なので
何故こうしていただいて上手く動いているのかじっくり追いかけてみます


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加