◀一般トップへ
  • 7030 正規表現置換で行削除したときの改行文字
    • 7035 Re:正規表現置換で行削除したときの改行文字
      • 7036 Re2:正規表現置換で行削除したときの改行文字
        • 7037 Re3:正規表現置換で行削除したときの改行文字
          • 7038 早速対応いただき、有難うございました
          • 7039 Re4:正規表現置換で行削除したときの改行文字
            • 7040 Re5:正規表現置換で行削除したときの改行文字
            • 7041 Re5:正規表現置換で行削除したときの改行文字
              • 7042 Re6:正規表現置換で行削除したときの改行文字
                • 7044 Re7:正規表現置換で行削除したときの改行文字
                  • 7045 Re8:正規表現置換で行削除したときの改行文字
                    • 7046 Re9:正規表現置換で行削除したときの改行文字
                      • 7048 Re10:正規表現置換で行削除したときの改行文字
                        • 7049 Re11:正規表現置換で行削除したときの改行文字
                        • 7050 Re11:正規表現置換で行削除したときの改行文字
                          • 7051 ご協力依頼です。CC:げんたさん
                            • 7052 Re:ご協力依頼です。
                              • 7053 メンバー登録しました
                                • 7054 よろしくお願いします。
  • [7030] 正規表現置換で行削除したときの改行文字 渡辺真 2009年09月19日 10:12

    Sakura 1.6.4.0 です。
    教えてください。既出なら申し訳ありません。

    正規表現置換で、置換前を
    ^.*$
    として、置換後を空白とすると、
    改行文字が↓になります。

    これは正しい動きですか?

    改行文字がCRLFの空白行に置換したい場合は、
    置換後に\rを入力しなければならないようです。
    • [7035] Re:正規表現置換で行削除したときの改行文字 syat 2009年09月21日 23:13

      ▼ 渡辺真さん
      > これは正しい動きですか?

      ずいぶん前からこういう動きだった気がして、それで慣れてましたが、
      考えてみると変ですね。
      「a$」だと a\r\n にマッチするのに、
      「.$」だと \r\n の部分にしかマッチしない。
      「.」の解釈が変?
      • [7036] Re2:正規表現置換で行削除したときの改行文字 名前 2009年09月22日 03:33

        > 行末文字の意味がライブラリでは \n固定なので、
        > これをごまかすために、ライブラリに渡すための検索・置換パターンを工夫する
        >
        > 行末文字($)が検索パターンの最後にあり、その直前が [\r\n] でない場合に、
        > 行末文字($)の手前に ([\r\n]+)を補って、置換パターンに $(nParen+1)を補う
        > というアルゴリズムを用いて、ごまかす。

        というようなコメントがありますので、. が \r にマッチするのは
        BREGEXP(bregonigも?)の仕様のようです。

        コメントによれば置換後の文字列に改行文字を補うトリックが
        使われているみたいですが。実際に使用された正規表現パターンが
        ^.*([\r\n]+)$
        だとすると .* の部分が \rを先に食べてしまっているために \nしか
        補えなかったみたいです。

        ----

        本題からそれますが、a$ の検索結果が\r\nも含めてマッチしてしまうのは
        上記のトリックの結果と考えられますが、何もしなければマッチなしに
        なってしまうので、それも問題でしょうね。

        ----

        検索語の行き過ぎたマッチはパターン中のエスケープされておらず、文字集合の
        中にない $ を (?=\r?\n|\r|$) に置き換えれば良さそうに思えます。> 開発者の方

        検索パターン中の先読みの有無をチェックするコードもあるようなので
        先読みを使用できない理由があるのかもしれませんが……。

        . が \r にマッチしてしまうのは、同じく . を [^\r\n] に置換すれば
        完全な非シングルラインモードになるでしょうか。\rと \nの扱いが
        異なる状態はなんとか解消してほしいものです。
        • [7037] Re3:正規表現置換で行削除したときの改行文字 名前 2009年09月23日 00:37

          先走って修正を試みました。
          こういう風になると嬉しいなあ、という動作になっていると思います。

          http://vvvvvv.sakura.ne.jp/ds14050/diary/20090922.html
          • [7038] 早速対応いただき、有難うございました 渡辺真 2009年09月25日 18:03

            > こういう風になると嬉しいなあ、という動作になっていると思います。

            有難うございます。
            削除した行の改行コードが、他の行とそろうようになりました。

            公式版への織り込みも期待しています。

            m(__)m

          • [7039] Re4:正規表現置換で行削除したときの改行文字 ryoji 2009年09月25日 18:11

            ▼ 名前さん
            > こういう風になると嬉しいなあ、という動作になっていると思います。

            ちょっと試してみました。
            行末にAを挿入することを意図して、
            置換前:$
            置換後:A
            の指定で*すべて置換*すると、CRLF改行の1行につき3箇所にAが挿入されてしまいますね。(CRの手前、LFの手前、次行の先頭)
            $周辺は、なかなか難敵な気がします...
            • [7040] Re5:正規表現置換で行削除したときの改行文字 名前 2009年09月25日 19:03

              ▼ ryojiさん
              > の指定で*すべて置換*すると、CRLF改行の1行につき3箇所にAが挿入されてしまいますね。(CRの手前、LFの手前、次行の先頭)

              本当ですね。逐一置換する場合には正常に動作するのを確認していたのですが……。
            • [7041] Re5:正規表現置換で行削除したときの改行文字 名前 2009年09月25日 20:48

              貴重な指摘ありがとうございます。

              置換する正規表現を修正してもう少しましな動作になるようにしました。
              しかし、(否定の)戻り読みに手を出してしまったせいで BREGEXP.DLLが蚊帳の外です。

              # 『「すべて置換」は置換の繰返し(&I)』を常時ONにすることも考えました。
              • [7042] Re6:正規表現置換で行削除したときの改行文字 ryoji 2009年09月25日 23:14

                今回の修正はBREGEXP.DLLには非対応とのことですが、そもそも従来の「$」の扱いには問題があったのでしょうか?
                素人考えでは、ヘルプにも書いてあるとおり、「.」が\n以外のすべての文字にマッチする(\rにもマッチ)という正規表現DLL側の仕様が今回の議論の発端であって、「$」のほうはまったく無実のような気がしたのですが…

                ---
                実は、「.」や「$」の扱いについては過去に何度も紆余曲折あったみたいなのですが、自分は門外漢でいたためよくわからないです。
                ていうか、正規表現自体に自信が無いんです~
                σ(^^;;;
                • [7044] Re7:正規表現置換で行削除したときの改行文字 名前 2009年09月26日 00:34

                  >「a$」だと a\r\n にマッチするのに、
                  >「.$」だと \r\n の部分にしかマッチしない。

                  $ が \r\n や \n にマッチするのが正確ではないんです。
                  $ は改行文字の手前や、文字列の最後の文字の直後の
                  位置(文字ではない)にマッチするものなので。

                  . を置き換えるのと同じ処理で $ を置き換えることも
                  可能だったので、実は、ついでです。

                  ----

                  >「.」や「$」の扱いについては過去に何度も紆余曲折

                  . や $ など「改行」に影響される特殊文字が改行を \n しか
                  認めていないのは、遠くは UNIX文化、直接は Perlの影響だろう
                  と思います。

                  今のままでも \r や \n を明示的に使用することで
                  思い通りの検索や置換を行うことはできますが面倒です。
                  エディタで使用する正規表現は書き捨てでしょうから
                  タイプの少なさは重要ですし、改行コードを対象にする
                  意図もないのに CRLFが LFに置き換わることがあれば、
                  常に下手な正規表現は書けないというようなプレッシャー
                  になります。

                  . が \r にマッチしなくなっても、改行文字を対象にしたい
                  人は \r, \n を使用してこれまでと同じ処理ができます。
                  (いままでもそうしていたと思います)
                  知らず改行コードを置換してしまう危険を防げることを
                  考えれば、広く普及した PCREといえどその仕様を変更する
                  のはありではないでしょうか。

                  $ も、サクラエディタ以外での一般的なマッチと結果をそろえる、
                  その上で、\r とマッチしない . とも整合性をとる目的で置き換えたいです。

                  $ はマッチが行き過ぎないためのストッパーとして、. とは関係なく
                  使用することがありますので、\r の次までいかれると困ります。
                  $ の代わりに (?=[\r\n]) は長すぎますし、誰も最初からはこう書きません。

                  最後の行の末尾にマッチしないことが問題であれば
                  (?=\r\n?|(?<!\r)\n)
                  の代わりに
                  (?=\r\n?|(?<!\r)\n|(?<[^\r\n])$)
                  を使用することで可能になると思います。
                  (最後が空行の場合だけはまだダメそうですが)
                  • [7045] Re8:正規表現置換で行削除したときの改行文字 ryoji 2009年09月26日 04:50

                    そうですね~。御意です。

                    自分も、
                    ・$ は\r, \n以外の文字と\r, \n, EOFとの境界にマッチする
                    ・. は \r, \n 以外のすべての文字にマッチする
                    のが実用上は望ましいんじゃないか?
                    ということには賛同します。

                    課題はいろいろ考えられますね。

                    1.検索文字の内部操作で副作用が発生しないこと
                     当初案で全置換時に起きたような奇妙な問題が起きないこと。

                    2.非対応となっているBREGEXP.DLL(ANSI版)への対処方法
                     ANSI版とUNICODE版は別仕様としてしまうのか?

                    3.$ が改行なし最終行のEOF手前ともマッチするように改善すること
                     $ を (?=\r\n?|(?<!\r)\n|(?<[^\r\n])$) に置き換える方法を試してみたけどエラーで動きませんでした。

                    4.検索強調表示が検索時の選択反転表示と一致すること
                     $ を (?=\r\n?|(?<!\r)\n) に置き換えた版で $ を検索すると、改行文字自体は選択反転表示にはならない(マッチしない)のに検索強調表示されている。
                     また、なぜか上方向検索では改行文字自体にマッチしたかのように選択反転表示になる。

                    5.正規表現キーワードでの $, . 指定も検索・置換と挙動が一致すること
                     現状、正規表現キーワードには $, . に検索・置換でやっているような細工が入っておらず、素の正規表現ライブラリ挙動になっている模様。
                     検索・置換時の . の細工([^\r\n]への置換)が追加されると、今よりも差異が大きくなって混乱しそう。

                    6.検索・置換や正規表現キーワードの複数行対応への順応性
                     これはやっぱり難しい?逆に小細工を一切しない方針にしたほうが容易かしら(もちろん、操作性は悪そうだけど開発に手間はかからない気ガス)。
                     検索・置換の複数行対応パッチが出てるけど、このあたりはどう対処してるのかな?

                    7.ヘルプ記載もちゃんと変更しなくちゃです

                    現状のままで変更しなくても、部分的にいくつか上記の問題はあるようですが…

                    う~ん。技術力も決断力も足りていない自分には荷が重すぎ…
                    問題発生しても保守の約束ができないレベルなので自ら手を下すのは遠慮しておきたいです(弱気)。

                    従来、正規表現周りを手がけてきた人や正規表現なら任せろ!的な人の参戦・主導を求む。
                    (^^;;;
                    • [7046] Re9:正規表現置換で行削除したときの改行文字 名前 2009年09月26日 10:13

                      些細な問題をとりあえずたたいておきます。

                      > 3.$ が改行なし最終行のEOF手前ともマッチするように改善すること
                      正しくは (?=\r\n?|(?<!\r)\n|(?<=[^\r\n])$) でした。
                      EOFのある行が空行の場合は、これでもやはりマッチしません
                      でしたが、たいした問題ではないと思います。

                      > なぜか上方向検索では改行文字自体にマッチしたかのように選択反転表示になる。
                      マッチ幅が 0のときの無限ループ対策として行われていた検索開始位置の
                      インクリメントが、マッチ範囲までを巻き込んでいました。
                      • [7048] Re10:正規表現置換で行削除したときの改行文字 ryoji 2009年09月26日 13:09

                        ▼ 名前さん
                        > > 3.$ が改行なし最終行のEOF手前ともマッチするように改善すること
                        > 正しくは (?=\r\n?|(?<!\r)\n|(?<=[^\r\n])$) でした。

                        これのかわりに ((?<![\r\n])($|(?=\r))) はいかが?
                        こいつは、
                        > > ・$ は\r, \n以外の文字と\r, \n, EOFとの境界にマッチする
                        のイメージを表現したものです。
                        どっちにしても () で括ってグループ化することになるので後方参照/置換用参照に追加されると思うけど、まぁ、それも良しとするのかな。

                        > EOFのある行が空行の場合は、これでもやはりマッチしません
                        > でしたが、たいした問題ではないと思います。

                        EOFのみ行は実質的な行として認めてない(行番号も表示してない)のでマッチしなくて良いと思います。
                        むしろ、置換でマッチして文字追加されたりすると実質的な行に変身することになるので都合が悪い気がします。
                        • [7049] Re11:正規表現置換で行削除したときの改行文字 通りすがり 2009年09月26日 14:07

                          ▼ ryojiさん
                          > EOFのみ行は実質的な行として認めてない(行番号も表示してない)のでマッチしなくて良いと思います。
                          > むしろ、置換でマッチして文字追加されたりすると実質的な行に変身することになるので都合が悪い気がします。
                          同意です。[EOF]のみの行でも行番号表示する某エディタで$を\.txtに置換したら、
                          最終行が.txt[EOF]となってしまい、好ましい動作ではありませんでした。


                          あとは名前さんとryojiさんの高度な正規表現議論についていけていないのですが、
                          ANSI版についてはLFCR改行の考慮もお忘れなく(Unicode版同様LFCR改行自体削除しても良い気もしますが)
                        • [7050] Re11:正規表現置換で行削除したときの改行文字 名前 2009年09月26日 21:35

                          > これのかわりに ((?<![\r\n])($|(?=\r))) はいかが?
                          シンプルでいいですね。キャプチャに含めない場合は
                          ( ) のかわりに (?: ) を使います。

                          $を先読みの中に入れる必要はないのですがこうすると括弧が減ります。

                          (?<![\r\n])(?=\r?$)
                          (?<![\r\n])(?=\r|$)

                          かっこでくくるのは $ に量指定子( ?, *, {n,m} )が
                          くっついていることを考慮してでしょうか。
                          置換前のパターンも置換後のパターンも文字を消費するものではないので
                          量指定子の存在が無意味だというのは同じで、必要ないとは思いますが。

                          (?:(?<![\r\n])(?=\r|$))
                          • [7051] ご協力依頼です。CC:げんたさん ryoji 2009年09月26日 22:32

                            ▼ 名前さん
                            > キャプチャに含めない場合は
                            > ( ) のかわりに (?: ) を使います。

                            φ(..)メモメモ...

                            > かっこでくくるのは $ に量指定子( ?, *, {n,m} )が
                            > くっついていることを考慮してでしょうか。

                            他の表現の中に結合されたときに意味が変わらないように、という保険的意味合いでくくってます。
                            あまり深く考えてません。(^^;;;

                            > 置換前のパターンも置換後のパターンも文字を消費するものではないので
                            > 量指定子の存在が無意味だというのは同じで、必要ないとは思いますが。

                            こういう少し突っ込んだコトには自信が無いので...σ(^^;

                            今回の変更は、できれば反映したい、けど自分はちょっと不安。
                            てことで、名前さん(呼びにくっっ)がいくらかしばらくの間サポートしてくださる”気持ち”があるのなら、とりあえず、まだベータテストの位置づけのUNICODE版に入れてしまおうかと思うのですが、いかがでしょうか?
                            (内部置換に利用するパターンにどれを選ぶかもお任せします)

                            ご希望であれば、開発メンバにも登録したいと思います。
                            いいですよね?げんたさん。
                            SourceForgeにメンバ登録していただいてメンバ名を教えていただければ。

                            あと、ライセンス明確化推進計画にもご協力いただければ...
                            http://sakura.qp.land.to/?Develop%2FLicenses
                            • [7052] Re:ご協力依頼です。 ds14050(使い捨ての名前をいつまでも引きず 2009年09月26日 23:13

                              サクラエディタは手になじんだ道具ですし、コミットした場合
                              相応の期間、自分のしたことの尻ぬぐいはするつもりです。

                              svn blame で表示される名前が ryojiでは申し訳ないので(svn praiseならまだしも!)
                              SourceForgeのアカウントもとってみようと思います。

                              ==(ここに書く予定)== アカウントは ds14050です。

                              • [7053] メンバー登録しました ryoji 2009年09月27日 00:18

                                ▼ ds14050(使い捨ての名前をいつまでも引きずさん
                                > ==(ここに書く予定)== アカウントは ds14050です。

                                メンバー登録しました。よろしくお願いします。

                                コミットルールは、原則、次のとおりです。

                                ANSI版:レビュー後にコミット可
                                http://members.at.infoseek.co.jp/sakura_editor/repositorymgmt.html

                                UNICODE版:レビュー無しでコミット可
                                >>unicode:646
                                • [7054] よろしくお願いします。 ds14050(っていたACです) 2009年09月27日 00:54

                                  粗相のないように努力しますので、よろしくお願いします。

                                  SourceForgeのこと、リポジトリルールのこと、一通り目を通してから
                                  コミットしようと思います。(その後ライセンスの表明も)