【ご教示お願い】正規表現No.40764
dszhm さん 23/08/06 08:01
 
環境は
OS:Windows 10 Pro 64Bit 22H2 Build 19045.3086
エディタ:9.19 64bit Float
です
秀丸マクロの変数やキーワードにマッチさせたくて
正規表現を
(?<=[^#$A-Za-z0-9_])[#$]{0,2}[A-Za-z_][A-Za-z0-9_]*(?![^#$A-Za-z0-9_])
としてみたのですが、秀丸上で検索してみると1文字欠落してヒットしています。
どこが誤っているのでしょうか?

[ ]
RE:40764 【ご教示お願い】正規表現No.40765
でるもんたいいじま さん 23/08/06 10:32
 
でるもんた・いいじまです。

> 秀丸マクロの変数やキーワードにマッチさせたくて
> 正規表現を
> (?<=[^#$A-Za-z0-9_])[#$]{0,2}[A-Za-z_][A-Za-z0-9_]*(?![^#$A-Za-z0-9_])
> としてみたのですが、秀丸上で検索してみると1文字欠落してヒットしています。
> どこが誤っているのでしょうか?

ご質問の件も含めて、問題箇所が3つあります。

☆ ☆ ☆

まず最初に、前方一致の「(?<=[^#$A-Za-z0-9_])」がそちらの意図したとおりの動作
をしてくれていません。
おそらく、[#$A-Za-z0-9_] の各記号がターゲット文字列の直前に存在しないこと、
という条件を付けたくてこのような書き方にしたのだと思います。
ところが、この記述の実際の意味は「[#$A-Za-z0-9_] 以外の文字が直前に1つ存在し
ていること。列挙した文字以外なら何でもいい。」です。
なので、変数名などが行頭(文字列とマッチングさせる場合はその冒頭)にある場合
は、そもそもこのパターンが機能してくれません。

結局この部分は、不一致指定の機能を使って
  (?<![#\$A-Za-z0-9_])
と書くのが正解のようです。中に \ を1文字追加させていただきましたが、これはあ
ってもなくてもかまいません。

☆ ☆ ☆

2点目。[#$]{0,2} とありますが、これだと $# や #$ にもマッチしてしまいます。
Keep it simple and stupid の精神で、たとえば (#|##|\$|\$\$)? なんていかがで
しょうか。
もちろん、(##?|\$\$?)? とか、(#{1,2}|\${1,2})? とか、他にも書き方は色々ある
と思います。

(補足)
なお、ここでは、\$ と書かずに単に $ と書いても大丈夫なはずです。ただしたとえ
ば、正規表現の最後尾に (xxx|yyy|$) のような記述があると、ズブズブと泥沼にハ
マってしまいます。なので、あくまで私の個人的なポリシーではありますが、「$ の
リテラルは常時エスケープする」ということにしています。

☆ ☆ ☆

そして最後に、今回お困りの「最後の1文字が欠ける」という件。
実はこれ、後方不一致指定の (?![^#$A-Za-z0-9_]) の部分を丸々削るのが正解のよ
うです。

「不一致」の機能については私自身も正確な挙動をイマイチ理解できていないのです
が、そもそも変数名・キーワード名本体部分を [A-Za-z_][A-Za-z0-9_]* と書いてい
て、この * は原則として最長一致部分にマッチするので、わざわざ後方不一致指定
で「余計なものまで巻き込まないでくれ」と念押しする必要性は全くないのです。

(補足)
既にご承知の話かもしれませんが、逆のパターンとして、
「"aaa", "bbb", and "ccc"」
というテキストから aaa、bbb、ccc をそれぞれ取り出そうとする場合、単に "(.+)"
 ではダメです。
この正規表現で検索すると、文字列全体で1回だけパターンにヒットし、\1 には「aa
a", "bbb", and "ccc」という長大なテキストが入ります。もちろん "(.*)" でも同
じです。

この場合は "(.+?)" や "(.*?)" を使うのがイマドキの定番です。ただし、正規表現
のエンジンが古すぎる環境では、"([^"]+)" や "([^"]*)" で代用せざるを得ないこ
ともあります。

☆ ☆ ☆

ではでは。がんばってください。

[ ]
RE:40765 【ご教示お願い】正規表現No.40766
dszhm さん 23/08/06 11:38
 
>でるもんた・いいじまです。
>
>> 秀丸マクロの変数やキーワードにマッチさせたくて
>> 正規表現を
>> (?<=[^#$A-Za-z0-9_])[#$]{0,2}[A-Za-z_][A-Za-z0-9_]*(?![^#$A-Za-z0-9_])
>> としてみたのですが、秀丸上で検索してみると1文字欠落してヒットしています。
>> どこが誤っているのでしょうか?
>
>ご質問の件も含めて、問題箇所が3つあります。

  (snip)

御教示の内容に従い修正することで、目的を達成することができました。
ありがとうございました。

[ ]