正規表現についてNo.34647
あべのり さん 15/12/07 15:49
 
あべのりです.hmjre.dllの正規表現に関して質問をさせてください.

次のマクロを動かしてみました.

loaddll hidemarudir + "\\hmjre.dll";
##pos = dllfunc("FindRegular","(?<=([^\\\\]|^)(\\\\\\\\)*)(\\$[0-9]+)","aiu\
n$0");

(エスケープされていない$[0-9]+を探そうという意図です.)#pos = 4を意図して
いたのですが,#pos = -1となってしまいました.なお,

#pos = dllfunc("FindRegular","(?\\3)([^\\\\]|^)(\\\\\\\\)*(\\$[0-9]+)","aiu\
n$0");

とすると意図通り#pos = 4となりました.また検索文字列から改行を消して"aiu$0"
としても検出がされるようです.

バグかなぁと思ってもいますがよくわかりません.

[ ]
RE:34647 正規表現についてNo.34648
秀まるお2 さん 15/12/07 17:20
 
 FindRegularでの「^」ですが、すみませんがこれは改行にはマッチしないです。
「^」は、普通の検索では行頭にヒットするってことになってますが、これは
「改行にヒットする」って意味ではなくて、あくまで検索対象文字列の先頭に
ヒットするって意味になります。

 なので例えば

    ##pos = dllfunc("FindReguar", "(?<=^)0", "aiu\n0";

 とかでもうまくヒットしないです。

 ならば、

    ##pos = dllfunc("FindReguar", "(?<=(^|\\n))0", "au\n0";

 とすればヒットするかというと、とりあえずヒットするケースもあるんですが、
実は「(?<=...)」の中には改行文字を含めることが出来ないって制限がありまし
て、うまくいかないことが多いです。

 なのでこの作戦も、すみませんが使えないです。

 やるとしたら、「ヒットした扱いにするタグ指定」を使う作戦があります。

    ##pos = dllfunc("FindRegular"
                   ,"(([^\\\\]|^)(\\\\\\\\)*)(\\$[0-9]+)(?\\2)"
                   ,"aiu\n$0");

 とするとうまくヒットします。

 そういう作戦でお願いするしか無いです。

 まとめると…

  − 「^」は、検索対象文字列の先頭にヒットするのみで、
    検索対象文字列の途中にある改行に長さゼロでヒットする
    パターンのつもりでは使えない。

  − (?<=....)の中に改行文字は入れられない。入れたい場合は
     (?<=pattern1)(pattern2)のような形にして
     (pattern1)(pattern2)(?\2) のように書き換える。

 でお願いします。

[ ]
RE:34648 正規表現についてNo.34649
あべのり さん 15/12/07 22:36
 
ご説明ありがとうございます.

loaddll hidemarudir + "\\hmjre.dll";
##pos = dllfunc("FindRegular","(?<=[^\\\\](\\\\\\\\)*)(\\$[0-9]+)","aiu\n$0");

としてみるとやはりヒットしないようですが,これは何故なのでしょう.([^\\\\]
が\nにマッチしてくれると期待したのですが.)

>実は「(?<=...)」の中には改行文字を含めることが出来ないって制限がありまし
>て、うまくいかないことが多いです。

のと同様「(?<=...)の中を改行にヒットさせようとしてもできない」という理解で良
いでしょうか?


[ ]
RE:34649 正規表現についてNo.34650
秀まるお2 さん 15/12/08 08:52
 
> としてみるとやはりヒットしないようですが,これは何故なのでしょう.([^\\\\]
> が\nにマッチしてくれると期待したのですが.)

 「^」の、HmJre.dllの中でのマッチングは、「検索対象文字列の先頭かどう
か」って判定ロジックになってます。

 ヒットする位置を仮に「x」としたら、「^」がヒットする条件は、

   xが0かどうか

 だけのロジックになってます。なので、検索対象文字列の途中にヒットするこ
とは無いです。

 秀丸エディタの検索ではそれで「行頭にヒットする」って意味になるのでそう
いう説明しかされてないですけども。

 34648番発言に書いた、

  − 「^」は、検索対象文字列の先頭にヒットするのみで、
    検索対象文字列の途中にある改行に長さゼロでヒットする
    パターンのつもりでは使えない。

 ということでお願いします。

[ ]
RE:34650 正規表現についてNo.34652
あべのり さん 15/12/08 16:11
 
(環境を書き忘れていましたが,Windows 10 + 秀丸8.56β17で試しています.)

> 「^」の、HmJre.dllの中でのマッチングは、「検索対象文字列の先頭かどう
>か」って判定ロジックになってます。
>
> ヒットする位置を仮に「x」としたら、「^」がヒットする条件は、
>
>   xが0かどうか
>
> だけのロジックになってます。なので、検索対象文字列の途中にヒットするこ
>とは無いです。

単なる"^"は行頭のみのマッチで了解しましたが,"[^\\\\]"ならばキャラクタクラス
での否定になって,「円マーク以外の文字にヒットする」ということになるかと思う
のですが,どうでしょう.

実際,message str(dllfunc("FindRegular","[^\\\\]","\\a"));では(私の)期待通
りaにマッチするようです.


これは別件ですが,HmJreのヘルプの「マクロからのdllfunc呼び出し」には,使えな
いと仰っていた「(?<=^|\n) 」のパターンが紹介されています.

[ ]
RE:34652 正規表現についてNo.34653
秀まるお2 さん 15/12/08 16:46
 
 すみません。[^....]を(^...)と勘違いして理解して返事書いてしまいました。

 ちゃんと理解してからお返事させていただきます。少々お待ちください。

[ ]
RE:34653 正規表現についてNo.34654
秀まるお2 さん 15/12/08 17:33
 
 今、ソースコードをトレースして原因がやっと分かりました。

 実は、

 (?<=.....)

 や

 (?<!.....)

 の中では改行文字が使えないって制限があると書きましたが、改行文字が使え
ないってだけじゃなくて、そもそも的に、ここの中が改行文字を含む文字列には
ヒットできない、みたいな制限があったようでした。

 ということでどうするかですが…

-----------------------------------------------------------------------
 その前にサンプルに改行を含む物があるのは、これの経緯を説明させていただ
きますと…

 実は以前は(?<=....)の中に改行文字を入れてもOKでした。その代わり、繰り
返し指定の「*」や「+」の類を入れることが出来ないって制限がありました。

 それからいろいろ改良して繰り返しパターンも使えるようにしたのですが、改
行文字にヒットするようなパターンでダメなケースを、後でIranoanさんから指
摘していただきました。それで仕方なく、改行文字を含むことが出来ないように
制限を入れて、ヘルプを直したり、秀丸エディタの検索ダイアログで警告を出す
ようにしたりしました。

 ですが、ヘルプのサンプルの中に改行文字を含む例があることは忘れてしまっ
てて、直せてませんでした。

 大変失礼しました。

 ただ、サンプルは、実はうまく動いたりします。実は(?<=....)の中に繰り返
しパターンが無ければ改行文字があってもヒットしたりします。

 ダメなのは、「改行文字にヒットする可能性があって、しかも繰り返し
パターンを含む場合」ってことになるようです。(今さら分かったことですが)
-----------------------------------------------------------------------

 とりあえず、秀丸エディタの検索ダイアログの方については、(?<=....)の中
が改行文字にヒットする可能性があって、しかも繰り返しパターンを含む場合に
限って警告を出すようにしようと思います。例えば

 (?<=[^a]b*)c

 みたいな検索をしたら警告を出すようにしようと思います。

 それとは別に、

 (?#frontmatchlinebreak)
 (?#frontunmatchlinebreak)

 みたいなコメントがあれば、(?<=....)の中が改行文字を含んでヒットするの
もありになる、みたいにしようと思います。

 さらに、FindRegular関数の場合は自動的にその指定がされた扱いにしてしま
おうと思います。

 そういう作戦でいいでしょうか。

[ ]
RE:34654 正規表現についてNo.34655
秀まるお2 さん 15/12/08 18:10
 
 やっぱり、

>  (?#frontmatchlinebreak)
>  (?#frontunmatchlinebreak)

 こういうのの追加はやめて、(?<=....)または(?<!....)の中身が改行にヒット
する可能性のある場合でもうまく動くように直そうと思います。

 改行にヒットする可能性がある場合に限ってはすごく遅くなるだけなので…。
変な制限があるよりは、遅くても正常動作する方がいいので。

 直してしばらくテストしてから、秀丸エディタ/秀丸メールのβ版の方に添付
させていただきます。それまでは、とりあえずは(?\2)を使う作戦などで回避お
願いします。

[ ]
RE:34655 正規表現についてNo.34656
あべのり さん 15/12/08 18:24
 
確かに秀丸から直接(?<=^|\n)を含む正規表現を実行したら警告が出ました.(先に
調べておくべきでした,すみません.)

> 直してしばらくテストしてから、秀丸エディタ/秀丸メールのβ版の方に添付
>させていただきます。それまでは、とりあえずは(?\2)を使う作戦などで回避お
>願いします。

ありがとうございます.ともかく動けば問題ないので,個人的には(?\2)を使う方法
で問題ありません.なので,単にヘルプに「改行は使えない/マッチしない」と書い
ておいてもらうのでも良いかなとも思います.仰るとおり動くならばそっちの方が良
いのは確かですが.

> 改行にヒットする可能性がある場合に限ってはすごく遅くなるだけなので…。
>変な制限があるよりは、遅くても正常動作する方がいいので。

動くようになった後も(?<=...)を使うよりは(?\2)の方が速いという意味でベターと
いう理解で良いでしょうか?

[ ]
RE:34656 正規表現についてNo.34657
あべのり さん 15/12/08 18:27
 
>ありがとうございます.ともかく動けば問題ないので,個人的には(?\2)を使う方法
>で問題ありません.なので,単にヘルプに「改行は使えない/マッチしない」と書い
>ておいてもらうのでも良いかなとも思います.仰るとおり動くならばそっちの方が
>良いのは確かですが.

(?<=...)はこれでも良いですが,(?<!...)は(?\2)を使う形では書きにくそうでした.
やはり改行もマッチするようにしてもらえるとありがたいです.

よろしくお願いします.

[ ]
RE:34655 正規表現についてNo.34668
あべのり さん 15/12/11 04:41
 
> こういうのの追加はやめて、(?<=....)または(?<!....)の中身が改行にヒット
>する可能性のある場合でもうまく動くように直そうと思います。

とりあえずあげた例は動くことを確認しました.ありがとうございます.

[ ]