HmJre.dllの仕様No.08507
山紫水明 さん 14/12/17 20:17
 

秀まるおさん,
正規表現の仕様についてお尋ねします。

「東京」,「京都」,「大阪」のいずれも含まない行を削除したいとき,以前は

replaceallfast "^(?!(?=.*東京|大阪|京都)).*\\n","",regular;

でできていたと思いますが,現在では全行が削除されてしまいます。
仕様変更になったのでしょうか?

 なお,
replaceallfast "^(?!.*(東京|大阪|京都)).*\\n", "", regular;
とすれば現在は可能です。
 公開マクロサポート会議室で提起されたものですから。

              山紫水明

[ ]
RE:08507 HmJre.dllの仕様No.08508
秀まるお さん 14/12/18 09:53
 
 後方不一致指定の中に後方一致指定が入れ子になるとどうなるかですが、ちょ
っとややこしいです。例えば

 (?!(?=aaa))

 はどこにヒットするのか調べてみたら、

 これは、

 (?!)

 というのがあって、それにヒットする場所に対して(?=aaa)のチェックがなさ
れる、みたいな解釈になるようです。

 それで、じゃぁ   (?!)  がどこにヒットするかですが、これは、空の
パターンに対して「?!」が指定されてることになります。空のパターンはどこに
でもヒットするので、結果、どこにもヒットしないのが意味的に正解になると思
います。

 どこにもヒットしない前提になってしまうので、(?=...)のところは何を指定
しても関係ないです。

 ということで、意味的解釈での仕様としては、

    ^(?!(?=.*東京|大阪|京都)).*\\n

 はどこにもヒットしない、となるべきだと思います。

 で、過去のバージョンも現在のバージョンも、どっちとも、意味的解釈での仕
様とは違う動きになってます。

 過去のバージョンについては…、たぶんバグってたんだと思います。すみませ
んが詳しい検証は省略させていただきます。

 で、問題は、現在のバージョンもおかしい点でして…、

 調べてみたら、(?!)が、行頭にのみ、間違ってヒットしています。これは…、
すみませんがバグになります。(?!)の中身が長さ0にヒットするケースについて、
行頭だけ間違ってヒットしてしまうようでした。なのでさっそくその点修正させ
ていただきます。

 バグ修正したHmJre.dllは、次の秀丸エディタのβ版に添付します。

 どっちにしてもマクロの方での正規表現パターンは直していただかないと仕方
が無いと思います。その点よろしくお願いします。

[ ]
RE:08508 HmJre.dllの仕様No.08511
山紫水明 さん 14/12/18 20:17
 
 秀まるおさん,

 丁寧な説明ありがとうございました。納得しました。

> どっちにしてもマクロの方での正規表現パターンは直していただかないと仕方
>が無いと思います。その点よろしくお願いします。

 了解しました。

 ところで,「東京」,「大阪」,「京都」のいずれも含まない行は
"^(?!.*(東京|大阪|京都)).*\\n"
でマッチさせることができます。他方,3語全部を含む行以外にマッチさせる場合
には,
"^(?!.*(東京.*大阪.*京都|東京.*京都.*大阪|京都.*東京.*大阪|京都.*大阪.*東京|
大阪.*東京.*京都|大阪.*京都.*東京)).*\\n"

と書けばできるようですが,もっと簡明,スマートな書き方はないでしょうか。

                    山紫水明

[ ]
RE:08508 HmJre.dllの仕様No.08512
colder さん 14/12/18 23:59
 
colderです。
hmjre.dll ver4.10を試してみて、ちょっと混乱しています。
ver4.10でも説明と異なる動作をしています。

> 後方不一致指定の中に後方一致指定が入れ子になるとどうなるかですが、ちょ
>っとややこしいです。例えば
>
> (?!(?=aaa))
>
> はどこにヒットするのか調べてみたら、
>
> これは、
>
> (?!)
>
> というのがあって、それにヒットする場所に対して(?=aaa)のチェックがなさ
>れる、みたいな解釈になるようです。
>
> それで、じゃぁ   (?!)  がどこにヒットするかですが、これは、空の
>パターンに対して「?!」が指定されてることになります。空のパターンはどこに
>でもヒットするので、結果、どこにもヒットしないのが意味的に正解になると思
>います。
> どこにもヒットしない前提になってしまうので、(?=...)のところは何を指定
>しても関係ないです。

ver4.10ではaaaが後に続かない0文字にヒットしているようです。
他の正規表現でも同じ動作のようで、これが正しい動作のような気がします。

[ ]
RE:08512 HmJre.dllの仕様No.08513
秀まるお さん 14/12/19 08:57
 
 すみません。(?!)でしかテストしてませんでしたが、改めて考えてみたら、

   (?!(?=aaa))

 は、

 ?!

 の中身がヒットしない所にヒットする訳で、そうすると、"aaa"じゃないとこ
ろ全部にヒットして正しいようです。

 では山紫水明さんの正規表現パターンがなぜヒットしないのか考えてみたら、
単純に、括弧が足りないだけでした。

^(?!(?=.*(東京|大阪|京都))).*\n

 でやったら、東京/大阪/京都を含む行にはヒットせず、他の行にはヒットしま
した。(HmJre.dll V4.10なら)

 どっちにしてもHmJre.dllがバグってたのが悪かったようです。すみません。

[ ]
RE:08511 HmJre.dllの仕様No.08514
秀まるお さん 14/12/19 09:17
 
 先ほどのcolderさんの話と関係してしまいますが、その場合こそが、?!と?=の
組み合わせで出来るってことなんだと思います。

 というか、いまさらながら、?!と?=の組み合わせの意味を理解したような…。
というか、いまさらながら、山紫水明さんがこういう目的で?!と?=の入れ子のや
り方を考案されたってことなのですね。

 で、まずは全部を含む行にヒットするのを考えてみました。

    ^(?=.*東京)(?=.*京都)(?=.*大阪).*\n

 とすれば全部の語を含む行にヒットするので、それを?!で反転させればいいよ
うです。

    ^(?!(?=.*東京)(?=.*京都)(?=.*大阪).*).*\n

 でとりあえず成功したような気がします。

 ちなみに

    ^(?!(?=.*東京)(?=.*京都)(?=.*大阪)).*\n

 でもうまくいく気がしますが、実際ダメでした。(理由よくわからず)

 仕組みがよく分かってないので、念のため

    ^(?!(?=.*東京)(?=.*京都)(?=.*大阪).*$).*\n

 としといた方がいいのかも。

----------サンプル---------------
x東京x            --> hit
x大阪xxx          --> hit
x今日x            --> hit
x東京x京都x       --> hit
x京都x大阪x       --> hit
x大阪x京都x       --> hit
x東京x京都x大阪x  --> not hit
x大阪x京都x東京x  --> not hit
----------サンプル---------------

 あと、改行で終わってないファイルも考えるなら、

    ^(?!(?=.*東京)(?=.*京都)(?=.*大阪).*$).*($|\n)

 の方がいいようです。

[ ]
RE:08514 HmJre.dllの仕様No.08516
山紫水明 さん 14/12/20 20:50
 
 秀まるおさん,

 いろいろ検証していただいてありがとうございます。

>    ^(?!(?=.*東京)(?=.*京都)(?=.*大阪).*).*\n
> でとりあえず成功したような気がします。

 これでできますね。すっきりしました。

> ちなみに
>    ^(?!(?=.*東京)(?=.*京都)(?=.*大阪)).*\n
> でもうまくいく気がしますが、実際ダメでした。(理由よくわからず)

 こちらではこれでもできました。あげていただいたやり方,全部OKです。

                    山紫水明

[ ]
RE:08516 HmJre.dllの仕様No.08517
秀まるお さん 14/12/22 13:48
 
>> でもうまくいく気がしますが、実際ダメでした。(理由よくわからず)
>
>  こちらではこれでもできました。あげていただいたやり方,全部OKです。

 改めてテストしたらこっちでも大丈夫でした。失礼しました。

[ ]