タグ付き置換の変な動作No.08661
杉浦 まさき さん 01/05/16 00:09
 
お久しぶりです。杉浦 まさき です。

正規表現と \f を使った後方参照置換で、
以下の置換が正常に動作していないようです(V3.08 で確認)。
確認の方よろしくお願い致します。

検索文字列: "^[^:]+\f:\f[^:]+$"
置換文字列: "\2:\0"

置換対象:

A:B

置換結果の予想:

B:A

置換結果:
B:
A

なんだか、"\nA:B" に対する入れ替えが行われているような動作です。

#ちなみに、"^.+\f:\f.+$" だとうまく行くんですよねぇ…不思議だ(^^;。


[ ]
RE:08661 タグ付き置換の変な動作No.08662
Arimac さん 01/05/16 00:51
 
>置換結果:
>B:
>A

BREGEXP.DLLだと
B
:A
になりますが、
確か[^:]とすると'\n'もマッチしたような
気がします。

#現在忙しいので検証はパス(^^;

[ ]
RE:08661 タグ付き置換の変な動作No.08663
TAKA さん 01/05/16 00:55
 
TAKA です。

>正規表現と \f を使った後方参照置換で、
>以下の置換が正常に動作していないようです(V3.08 で確認)。
>確認の方よろしくお願い致します。
>
>検索文字列: "^[^:]+\f:\f[^:]+$"
>置換文字列: "\2:\0"

もっとシンプルに再現しました。

"[^a]+"で検索すると、"A:B\n"のように改行が含まれて検索されて
しまいます。

".+"で検索すると、"A:B"のように正常に検索されます。

でも、"[^a]+"の正規表現は"a"以外の繰り返しなので、改行も対象
になるというのは正しい結果だと思います。
改行が1個しか検索されませんでしたが、これは不具合かも。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

意図した結果を得たいなら、検索文字列に"^[^:\n]+\f:\f[^:\n]+"
を指定すべきだと思います。
本当は、"^[^:\n]+\f:\f[^:\n]+$"のように最後に"$"をつけても正
                                       ^^^^^^^^^^^^^^^^^^^^^
常に動作してもよさそうですが駄目でした。これは、不具合かもし
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
れませんね。
^^^^^^^^^^^^

私は、正規表現はあまり得意ではありませんので、間違っているか
もしれませんが。

[ ]
RE:08663 タグ付き置換の変な動作No.08664
TAKA さん 01/05/16 01:09
 
TAKA です。

>改行が1個しか検索されませんでしたが、これは不具合かも。

秀丸ヘルプの「\nを使った複数行検索の際の制限について」に

> 秀丸エディタでは検索元文字列の中に「\n」がいくつ含まれてい
>るかを計算し、その数+1の行まで検索でヒット可能にします。そう
>いう特殊な仕組みのため、\n自体を任意の回数繰り返すような正規
>表現は、期待通りに動作しないことがあります。

という記述があり、この制限に引っかかっただけのようです。


後は、"^[^:\n]+\f:\f[^:\n]+$"で検索出来ないのが、謎です。

[ ]
RE:08664 タグ付き置換の変な動作No.08667
ENCODINGSHIFTJIS さん 01/05/16 11:49
 
>後は、"^[^:\n]+\f:\f[^:\n]+$"で検索出来ないのが、謎です。

使えない方法しか、見つかりませんでした。

\n を \x0A にして検索する。    
^[^:
]+\f:\f[^:
]+
    行末の $ は無し ??  Webでは改行しているが1行です
\x0A を入力するには 一行マクロ        overwrite "\x0A";
を編集面で実行し検索文字列を作成し、それをカット&ペーストで
検索ダイアログに入力する。
結果はまあまあだが、確信はないです。

[ ]
RE:08664 タグ付き置換の変な動作No.08670
秀丸担当 さん 01/05/16 17:37
 
>後は、"^[^:\n]+\f:\f[^:\n]+$"で検索出来ないのが、謎です。

やってみたところ、確かにできません。
このケースの場合\fを削るだけで、秀丸が特にいじることなく
処理していました。JREの問題でしょうか。
Arimacさんの見解としてはどうでしょう。


[ ]
RE:08664 タグ付き置換の変な動作No.08671
TAKA さん 01/05/16 19:30
 
TAKA です。

>後は、"^[^:\n]+\f:\f[^:\n]+$"で検索出来ないのが、謎です。

役に立つ情報かどうか分かりませんが、新たなことが分かりました。

正規表現で「[^\n]+$」を検索すると、テストファイル1では、意
図通り「TEST」にヒットしますが、テストファイル2では、ヒット
しません。

// テストファイル1(ここから)
\n
TEST\n
[EOF]
// テストファイル1(ここまで)

// テストファイル2(ここから)
\n
TEST\n
\n
[EOF]
// テストファイル2(ここまで)

\nは改行で[EOF]はファイルの最後です。

[ ]
RE:08670 タグ付き置換の変な動作No.08673
Arimac さん 01/05/16 23:53
 
検索文字列:"^[^:\n]+\f:\f[^:\n]+$"
置換文字列:"\2:\0"
検索対象:
A:B
A:B
A:B
[EOF]
とした場合
BREGEXP.DLLでは最後の1行以外は置換されました。
最後の1行が置換されないのはパターンに'\n'が
2個含まれるため、秀丸エディタが最後の行は
マッチしないであろうと判断して渡してこない
からのようです。
 
JRE32.DLLで置換されないのはJRE32.DLLでは渡された
バッファの最後の'\n'の直前にしか'$'がマッチしない
からのようです。
つまり、"TEST\n\n"のような感じで渡された場合、
最初の'\n'の直前では'$'はマッチしません。
 
BREGIF.DLLではマルチラインのオプションを使って
バッファの途中の'\n'の直前でも'$'がマッチする
ようにしています(^^;

[ ]
RE:08663 タグ付き置換の変な動作No.08674
杉浦 まさき さん 01/05/17 00:17
 
TAKA さん、こんばんは。
杉浦 まさき です。

本題からはちと外れますが…

>でも、"[^a]+"の正規表現は"a"以外の繰り返しなので、改行も対象
>になるというのは正しい結果だと思います。

[^, ] による否定の場合も改行文字は含まれないのが正しいです。
#ってもキャラクタクラス指定は実装依存のような気がするので
 「正しい」というのは言い過ぎかもしれないです。
 「多くの正規表現検索エンジンでは…となっています」かな(^^;?
#過去のバージョンでは確かそうなってたし、
 Q&A集もそういう前提で書いてるので、
 今更変えられても困るなぁ(ToT)。


[ ]
RE:08674 タグ付き置換の変な動作No.08675
杉浦 まさき さん 01/05/17 00:48
 
こんばんは。一人ボケツッコミの杉浦です。

> Q&A集もそういう前提で書いてるので、

大ウソこいてましたm(_ _)m。
その事には触れたはず…と勘違いしたまま書いてしまいました。
というわけで、先日送った改訂版はボツにして下さいm(_ _)m。>JRくん


[ ]
RE:08674 タグ付き置換の変な動作No.08676
Arimac さん 01/05/17 01:17
 
>[^, ] による否定の場合も改行文字は含まれないのが正しいです。

古い正規表現のヘルプでは確かに「改行文字は含まれない」と
書かれていますが、現在では新しい正規表現というもの確立
しているようで、そちらでは特に書かれていないので
「改行文字も含む」と取っても間違いではないと思います。
 
参考:http://www.linux.or.jp/JM/html/LDP_man-pages/man7/regex.7.html

[ ]
RE:08673 タグ付き置換の変な動作No.08681
秀丸担当 さん 01/05/17 17:32
 
>JRE32.DLLで置換されないのはJRE32.DLLでは渡された
>バッファの最後の'\n'の直前にしか'$'がマッチしない
>からのようです。

なるほど。ありがとうございます。
今回はやはり特殊なケースということもあり、
JREの仕様ですね。

[ ]
RE:08671 タグ付き置換の変な動作No.08682
秀丸担当 さん 01/05/17 17:32
 
>正規表現で「[^\n]+$」を検索すると、テストファイル1では、意
>図通り「TEST」にヒットしますが、テストファイル2では、ヒット
>しません。

Arimacも指摘されていますが、最後の行だけ動作が違うように
なるのは変なので何とか修正したいところです。


[ ]
RE:08681 タグ付き置換の変な動作No.08690
TAKA さん 01/05/17 20:19
 
TAKA です。

>>JRE32.DLLで置換されないのはJRE32.DLLでは渡された
>>バッファの最後の'\n'の直前にしか'$'がマッチしない
>>からのようです。
>
>なるほど。ありがとうございます。
>今回はやはり特殊なケースということもあり、
>JREの仕様ですね。

JREにはマルチラインのオプションがないのでしょうか?
もしあれば、そのオプションを指定するだけだと思うのですが。
オプションがなければ、「$」を使用する際の注意事項をヘルプに
書いて頂けたらと思います。 > 秀丸担当さん

Q&A集の方は、お願いします。 > 杉浦 まさきさん

[ ]
RE:08676 タグ付き置換の変な動作No.08697
杉浦 まさき さん 01/05/18 00:16
 
Arimac さん、こんばんは。
杉浦 まさき です。

>古い正規表現のヘルプでは確かに「改行文字は含まれない」と
>書かれていますが、現在では新しい正規表現というもの確立
>しているようで、そちらでは特に書かれていないので
>「改行文字も含む」と取っても間違いではないと思います。

むぅ、ご紹介頂いたページを見た所、どうもそのようですね…。
#というか、正規表現が POSIX で定義されていたとは…知らんかった(^^;。

ただ、[^ ] に改行文字を含むようにした場合、
それはそれで実装が大変な気がしますが、
その辺 JRE とか bregexp はどう扱っているんでしょうか?
#"[^\a]+" で普通のテキストファイルを検索した場合とか…
 関数側で「もっとマッチする可能性があるから
 次の文字列をよこせ〜」とか言ってくれる仕様じゃなければ…
 僕なら逃げます(^^;。


[ ]
RE:08697 タグ付き置換の変な動作No.08698
Arimac さん 01/05/18 01:02
 
「もっとマッチする可能性があるからよこせ」という
仕様は正規表現の関数側の実装が大変な気がします(^^;
 
JRE32.DLLやBREGEXP.DLLでは'\0'で終わるsjisの
バッファを渡してもらって検索しています。
 
秀丸エディタはこれらの関数を呼び出すたびに
内部コード(最新版はunicode?)をsjisに変換し
関数から返却されたsjisでのバイト位置から
カーソル位置を求めるという面倒な事をしている
筈です(^^;
 
grepとかは直接テキストのバッファを検索している
のではないでしょうか?(試した事はないです)
sedとかはバッファに取り込む行自体を正規表現で
指定できるようになっています。

[ ]
RE:08690 タグ付き置換の変な動作No.08699
ENCODINGSHIFTJIS さん 01/05/18 10:49
 
結果だけを追求するなら $ をあきらめて \f\n

検索文字列
^[^:\n]+\f:\f[^:\n]+\f\n
置換文字列
\2:\0\n

?

[ ]
RE:08699 タグ付き置換の変な動作No.08701
TAKA さん 01/05/18 12:03
 
TAKA です。

>結果だけを追求するなら $ をあきらめて \f\n
>
>検索文字列
>^[^:\n]+\f:\f[^:\n]+\f\n
>置換文字列
>\2:\0\n

現在の話題は、「8663」に書いてある、

>意図した結果を得たいなら、検索文字列に"^[^:\n]+\f:\f[^:\n]+"
>を指定すべきだと思います。
>本当は、"^[^:\n]+\f:\f[^:\n]+$"のように最後に"$"をつけても正
>                                       ^^^^^^^^^^^^^^^^^^^^^
>常に動作してもよさそうですが駄目でした。これは、不具合かもし
>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>れませんね。
>^^^^^^^^^^^^

に移っていますが、[EOF]で終わった行も正常に置換してい欲しい
ので、「\n」ではなく、「$」を使いたいのだと思います。
#「8690」で書いたように、JREにマルチラインのオプションがな
 ければお手上げかもしれません。もしくは、BREGIFを使うか。

「A:B:」にヒットさせないためには、最後に「\n」か「$」を指定
したいですが、[EOF]で終わった行も対象にするには、「$」しかな
いと思います。
#例外として、あきらめるという方法もありますが。

[ ]
RE:08701 タグ付き置換の変な動作No.08705
ENCODINGSHIFTJIS さん 01/05/18 14:49
 
正規表現の $ や ^ は行の前後や開始位置に敏感らしい。

^[^:\n]+\f:\f[^:\n]+$
[EOF]行の行頭から検索するとマッチする

^[^:]+\f:\f[^:\n]+$
検索と置換で反転表示が違う(検索でシミュレートする時 ! )
空白行が直前にあるとマッチする
[EOF]行ではカーソルを行頭に置くとマッチする

---------------- テストデータ ---
asfjlasjkf:jjjjjjjj
saldflsd


s

fffffffff:aaaaaa
jjjjjjjjjj:gggggggggggg
jjjjjjjjjj:gggggggggggg

jjjjjj7jjjj:gggggggggggg
jjjjjjjjjj:gggggggggggg
gggggggg:ujuuuuuuuu

                 
jjjjjjjjjj:gggggggggggg[EOF]
-----------------------------------
思い出せないが、改行↓から開始するとマッチする正規表現も
あったような。


[ ]
RE:08705 タグ付き置換の変な動作No.08706
TAKA さん 01/05/18 19:03
 
TAKA です。

>^[^:\n]+\f:\f[^:\n]+$
>[EOF]行の行頭から検索するとマッチする

理由は、正規表現内に「\n」が2個あるため、秀丸側では3行分ま
でのデータを渡します。この場合は、1行しかありませんので1行
です。
「$」は渡されたデータにある最後の「\n」の直前、もしくはデー
タの最後しかヒットしません。
そのため、「jjjjjjjjjj:gggggggggggg」ではヒットします。
(データの最後としてヒット)
他のデータ、「asfjlasjkf:jjjjjjjj\nsaldflsd\n\n」ではヒット
しません。
(「$」までの正規表現では「asfjlasjkf:jjjjjjjj」にヒットした
が、その次の\nがデータの最後でないため、ヒットしない)

マルチラインに対応するオプションがあれば、解決します。

「8673」の
>最後の1行が置換されないのはパターンに'\n'が
>2個含まれるため、秀丸エディタが最後の行は
>マッチしないであろうと判断して渡してこない
>からのようです。

から判断すると、現在は検索されないのが普通ですが、カーソルが
ある行は無条件に対象データとするという仕様があるようですね。


>^[^:]+\f:\f[^:\n]+$
>検索と置換で反転表示が違う(検索でシミュレートする時 ! )

これは、点滅表示のときは、ヒットした先頭からヒットした文字分
だけ点滅させるという仕様です。
「8514」を参照。


>空白行が直前にあるとマッチする

理由は、正規表現内に「\n」が1個あるため、秀丸側では2行分の
データを渡します。
「\nfffffffff:aaaaaa\n」というデータはヒットしますが、
「fffffffff:aaaaaa\njjjjjjjjjj:gggggggggggg\n」というデータ
はヒットしません。
これは、最初の理由とほぼ一緒ですね。

これも、マルチラインに対応するオプションがあれば、解決します。


>[EOF]行ではカーソルを行頭に置くとマッチする

これは、最初の理由と一緒ですね。


JREにマルチラインのオプションがあることを祈るのみです。
もしくは、秀丸側で、
asfjlasjkf:jjjjjjjj\nsaldflsd\n\n
asfjlasjkf:jjjjjjjj\nsaldflsd\n
asfjlasjkf:jjjjjjjj\nsaldflsd
asfjlasjkf:jjjjjjjj\n
asfjlasjkf:jjjjjjjj
のような順番でデータを渡すということでも可能だと思います。
(この処理が必要になるのは、「\n」と「$」がある場合のみ)

いかがでしょうか? > 秀丸担当さん

[ ]
RE:08698 タグ付き置換の変な動作No.08710
杉浦 まさき さん 01/05/19 01:22
 
Arimac さん、こんばんは。
杉浦 まさき です。

>秀丸エディタはこれらの関数を呼び出すたびに
>内部コード(最新版はunicode?)をsjisに変換し
>関数から返却されたsjisでのバイト位置から
>カーソル位置を求めるという面倒な事をしている
>筈です(^^;

内部コードが unicode だと確かに大変そうですね(^^;。
そういう一方で、バイト位置->カーソル位置は
それほどでもない気が…。<人の苦労を考えない奴(^^;
#っても sjis -> unicode も API 一発?だし、
 実際それほどオーバーヘッドがあるのかなぁ…??

>grepとかは直接テキストのバッファを検索している
>のではないでしょうか?(試した事はないです)

この手のツールはストリームを片っ端から
読んでいけばいいだけなんで割と簡単に複数行マッチも
実装できると思いますが…実際の所どうなんでしょうね(^^;?

>sedとかはバッファに取り込む行自体を正規表現で
>指定できるようになっています。

あれ?…コマンドで明示的に複数行を読み込まないと
駄目なんじゃないんでしたっけ??
#う〜ん、いずれにしてもまだまだ勉強が足らないです。>σ(^^;


[ ]
RE:08710 タグ付き置換の変な動作No.08723
Arimac さん 01/05/19 22:34
 
>内部コードが unicode だと確かに大変そうですね(^^;。
>そういう一方で、バイト位置->カーソル位置は
>それほどでもない気が…。<人の苦労を考えない奴(^^;
>#っても sjis -> unicode も API 一発?だし、
> 実際それほどオーバーヘッドがあるのかなぁ…??
 
さらにはタブや行の折り返しも考慮しなければならないので
ちょっとしたオーバーヘッドはあると思います。
でも最近の超高速CPUの前では微々たるものでしょうが(^^;
 
>あれ?…コマンドで明示的に複数行を読み込まないと
>駄目なんじゃないんでしたっけ??
>#う〜ん、いずれにしてもまだまだ勉強が足らないです。>σ(^^;
 
書き方が悪かったみたいです(^^;
sedではバッファに取り込まない限り複数行の処理ができないので、
バッファに取り込む行の範囲の指定(アドレス指定)も正規表現
(ただしこちらは行内でのマッチのみ)でできるようにしていると
言いたかったのです(^^;
杉浦まさきさんの認識通りです(^^;
ただし最近はunixから遠ざかっているので嘘を言ってるかも
知れません(^^;

[ ]
RE:08706 タグ付き置換の変な動作No.08767
秀丸担当 さん 01/05/21 17:47
 
>JREにマルチラインのオプションがあることを祈るのみです。
>もしくは、秀丸側で、
>asfjlasjkf:jjjjjjjj\nsaldflsd\n\n
>asfjlasjkf:jjjjjjjj\nsaldflsd\n
>asfjlasjkf:jjjjjjjj\nsaldflsd
>asfjlasjkf:jjjjjjjj\n
>asfjlasjkf:jjjjjjjj
>のような順番でデータを渡すということでも可能だと思います。
>(この処理が必要になるのは、「\n」と「$」がある場合のみ)

JREにマルチラインのオプションというのは無いです。(と思う)
「\n」と「$」がある場合のみ上記のような動作にするですか・・
確かに、できるかもしれないです。
しかし検索にこの対策を入れるのにはちょっと抵抗があります。

[ ]
RE:08767 タグ付き置換の変な動作No.08775
TAKA さん 01/05/21 19:21
 
TAKA です。

>JREにマルチラインのオプションというのは無いです。(と思う)

残念。


>「\n」と「$」がある場合のみ上記のような動作にするですか・・
>確かに、できるかもしれないです。
>しかし検索にこの対策を入れるのにはちょっと抵抗があります。

レスポンスのこともありますし、めったに指定しないような表現な
ので、私は現状のままで問題ありません。
#Q&A集には書いて欲しいところですが。

[ ]
RE:08775 タグ付き置換の変な動作No.08781
杉浦 まさき さん 01/05/22 00:11
 
ども、杉浦 まさき です。

>#Q&A集には書いて欲しいところですが。

[^a] が \n にマッチするという時点で
いずれにしても書き直しです(ToT)。
#あと、bregif にも触れるべきですね。
 というわけでもうちょい頑張ってみます…。


[ ]