正規表現ユニット SkRegExp で行頭検索の挙動

解決


Terry  2021-03-28 05:08:31  No: 149626  IP: [192.*.*.*]

いつもお世話になっています、Terry です

正規表現「^」だけで行頭検索をした場合改行のみ存在する文字列とその他の文字を含んだ文字列で結果が違って困っています
秀丸やMeryなどで試したところ問題なくヒットするので正規表現オプションの問題かと調べてみましたがわかりませんでした


Delphi2009 + SkRegExp(3.0.8 2015/5/30 for Delhi 2005 later)

procedure TForm1.Button1Click(Sender: TObject);
var
  r:TSkRegExp;
  S:string;
begin
  r := TSkRegExp.Create;
  try
    r.Options:=r.Options+[roMultiLine];
    r.Expression := '^';
    Memo1.Lines.Add('-- #13 x 4');
    S:=#13#13#13#13;
    if r.Exec (S) then
    begin
      repeat
        Memo1.Lines.Add(
          IntToStr(r.Groups[0].Index));
      until not r.ExecNext;
    end;
    Memo1.Lines.Add('-- #13 + a#13 + #13 + #13');
    S:=#13+'a'+#13+#13#13;
    if r.Exec (S) then
    begin
      repeat
        Memo1.Lines.Add(
          IntToStr(r.Groups[0].Index));
      until not r.ExecNext;
    end;
    Memo1.Lines.Add('-- #13 + a#13 + #13 + #13a');
    S:=#13+'a'+#13+#13#13+'a';
    if r.Exec (S) then
    begin
      repeat
        Memo1.Lines.Add(
          IntToStr(r.Groups[0].Index));
      until not r.ExecNext;
    end;
  finally
    r.Free;
  end;
end;

結果
-- #13 x 4
1
2
3
4
-- #13 + a#13 + #13 + #13
1
2
-- #13 + a#13 + #13 + #13a
1
2
6


以上、よろしくお願いいたします

編集 削除
Mr.XRAY  2021-03-30 01:32:08  No: 149632  IP: [192.*.*.*]

正規表現の ^ は ^ に続く文字が行の先頭に存在するかを検索するのだと思うのです.
ということは,^ だけを使用するのは考えられません.
先頭が #13 を検索するには

  r.Expression := '^\r'

ということになります. 提示されている例だと,こんな感じでしょうか.

  r.Expression := '^\r|a';
    
文字位置の検索のようなので・・・ 勘違いしていたらゴメンナさい.    

編集 削除
Mr.XRAY  2021-03-30 01:35:20  No: 149633  IP: [192.*.*.*]

> 正規表現の ^ は ^ に続く文字が行の先頭

ゴメンナさい.文字ではなく文字列ですね.

編集 削除
Terry  2021-03-30 10:30:04  No: 149634  IP: [192.*.*.*]

Mr.XRAY 様、ご回答ありがとうございます

私自身もそのように理解していたのですがユーザーから
「行頭に空白をいれたくて、正規表現の"^"で置換しようとしたのですが、(中略)他のテキストエディタでは、行頭の検索ができました。」と報告があり
実際に他のエディタで確かめれば確かめるほど全てのエディタで動作したのです
さらには https://regex101.com までもが(x.x)

ですので私の使い方に間違いがあるのならその部分を正して SkRegExp を使い続けたいのですが
もしその点が未対応なのなら鬼車や鬼雲の様な他のライブラリだと対応しているのかとか
どうせ DLL 使うのなら秀丸の HMJRE.DLL の方が安心だろうかと悩んでいた次第です

編集 削除
Mr.XRAY  2021-03-30 11:17:43  No: 149635  IP: [192.*.*.*]

^ の後ろに何もない場合,それは正確には,行頭に何も文字がないことになります.

全ての文字には数値が割り当てられています.文字コード (コードポイント)です.
文字がないと言う文字,Null 文字でも #0 という数値が割り当てられています.
つまり,全ての行頭には非可視文字も含めて何かしらの文字があるわけです.

おそらく,推測ですが,^ を単独で使用することを考慮したライブラリでは,
全ての行を検出するようにしているのではないでしょうか (あまり意味があるとは思えませんが).
そのライブラリに説明があるかも知れません.
SkRegExp はそのようになっていないのかも知れません.

編集 削除
Mr.XRAY  2021-03-30 11:32:40  No: 149636  IP: [192.*.*.*]

> 全ての行を検出するようにしているのではないでしょうか (あまり意味があるとは思えませんが). 

行頭の文字が何であるかを検出しているわけではないと思うので.
^ を使用する意味がないと言う意味です.
でも,もしかしたら行頭の文字が取得できるようになっていたりして.

編集 削除
Terry  2021-03-30 12:02:58  No: 149637  IP: [192.*.*.*]

ありがとうございました
もう少し SkRegExp のソースを読んでから他のライブラリに当たってみることにします

編集 削除
Terry  2021-03-31 11:42:33  No: 149641  IP: [192.*.*.*]

情けないですがとりあえず
検索内容が「^」のみの時以下の内容で内部処理することにしました
^.{0}|$^|.{0}\z

編集 削除