正規表現による置換が意図した通りにならNo.32187
はりー さん 13/04/15 06:31
 
昨日、初めて秀丸をインストールし試用してみましたが、正規表現による置換が
標準的な正規表現によるものと著しく異なる結果となり、大変難儀しました。

バージョン:hm822_signed.exe (日本語版) 32bit Ver8.22 2013/03/01

下記が最小パターンの例です。
これはバグでしょうか? それとも仕様でしょうか?
もしこれが仕様であるならば、どのような解釈でこの結果になるのか知りたいです。

===========================================================
■検索
((A.)+).*

■置換
\1

-----------------------------------------------------------
■対象文字列
A1A2A3あいうえお
AaAbAcかきくけこ
AいAろAはさしすせそ

■期待する結果
A1A2A3
AaAbAc
AいAろAは

■実際の結果(HmJre.dll)
A1
Aa
Aい

===========================================================

[ ]
RE:32187 正規表現による置換が意図した通No.32188
秀まるお2 さん 13/04/15 09:42
 
 これは、すみませんが一応仕様になります。

 「.*」は、それ自体が「A…」のような文字列も含めてヒットしてしまいまし
て、今回のケースは、例えば

    A1A2A3あいうえお

 の場合は、((A.)+)の部分が先頭の「A1」にだけヒットして、.*の部分が
「A2A3あいうえお」にヒットしてしまってるようです。

 正規表現の解釈的にはそれもありで、内部的な処理の都合でたまたま
「.*」の方にもっとも長くヒットするのが優先されてしまうようです。

 ((A.)+)が、確実に期待した文字列(一番長い文字列)にヒットにするために
は、

    ((A.)+)(?!A).*

 のように後方不一致指定を使う作戦がお勧めです。

 後方不一致指定を使わずに書くとしたら、

    ((A.)+)(|[^A\n].*)

 のような、ちょっとややこしい正規表現でないとダメみたいです。

[ ]
RE:32188 正規表現による置換が意図した通No.32189
秀まるお2 さん 13/04/15 09:53
 
 すません。先ほどの正規表現だと、例えば

    a1a

 のような文字列を「a1」に置換するのがうまくいきませんでした。

 正しくは、


    ((A.)+)(?!A.).*


 か、または


    ((A.)+)(|[^A].).*$


 でいけるようです。置換するだけなら

    ((A.)+)(?!A.).+

 が一番ベストかなぁと思います。

[ ]
RE:32187 正規表現による置換が意図した通No.32191
アルビレオ さん 13/04/15 13:12
 
ユーザーのアルビレオです。

■検索
(?<=A.)[^A\n]*

■置換
(空欄)

でもいけそうです。

パターンの中に可変長の部分が複数あるとき、どちらを長く取るかは厳密な仕様
がないため、可能ならば繰り返し記号はひとつしか使わない方が意図した結果を
得られやすいです。

[ ]