2

私の貪欲な複数行の正規表現がVimで重複する一致を与えていることに気付いたとき、私は驚きました。正規表現は、テキストのブロック全体、または連続する非空白行に一致するように設計されています。

正規表現は、私が期待したすべてのものと一致したようです(強調表示は正しく見えました)がn、次のブロックにスキップする代わりに次の一致にスキップするために使用すると、現在のブロックの次の行に移動しました。

これが私が使用していた正規表現です((.+\n){1,}ほとんどの正規表現エンジンに相当します):

\(.\+\n\)\{1,}

これは、少なくとも1つの空でない行、およびできるだけ多くの連続する空でない行と一致する必要があります。テキストファイルの例を次に示します。

block 1
some stuff
more stuff

block 2
foo bar
baz qux

この正規表現(/\(.\+\n\)\{1,}+ Enter)を適用すると、2つのブロックが正しく強調表示されますが、各ブロックに1つずつ、正規表現が一致するのは2つだけであると予想されます。ただし、を押しnて次の正規表現の一致に進むと、空でない各行が正規表現と一致しているように見えるため、カーソルは最初の行から始まりn、2行目、3行目、ブロックの先頭に移動します。 2など。

n次の行ではなく次のブロックに進むように、各ブロックの予想される動作が単一の一致であることがわかるように、正規表現を変更するにはどうすればよいですか?

また、この動作がドキュメントのどこかにあるかどうか、またはこの動作を変更するオプションがあるかどうかを知りたいと思います。検索/置換で同じ正規表現を使用する場合、動作は私が期待するものであることに注意してください(置換は2回だけ適用され、ブロックごとに1回適用されます)。

4

2 に答える 2

4

次の正規表現が機能しているようです。

\(\%^\|^\n\)\zs\(.\+\n\)\+

説明:

\(             # start of group
  \%^          # beginning of file
    \|         # OR
  ^\n          # a blank line
\)             # end of group
\zs            # start matching here
\(.\+\n\)\+    # at least one non-blank line

非常に魔法のオプションを使用すると、長さを少し減らすことができます。

\v(%^|^\n)\zs(.+\n)+

誰かがより短い解決策を思い付くことができるかどうかを楽しみにしています!

zigdon の答えは、なぜそのような振る舞いなのかをよりよく理解するのに役立ちました。を使用して次の一致にジャンプするnと、次の一致する位置が前の一致に含まれていたとしても、カーソルの現在の位置から正規表現の最初の一致が検索されます。これが、正規表現をブロックの先頭に固定する必要があるように見える理由です。

最初のグループで不必要な先読みを取り除くのを手伝ってくれた Nolen Royal に感謝します。

于 2012-04-09T22:08:45.290 に答える
2

あなたの一致は「1つ以上の空でない行に一致する」と言っているので、同じ段落内で複数回一致する可能性があります。これを修正するには、カーソルを一致の最後に配置するように指定できます。これは、次の一致が段落の最後から開始されることを意味します。\zsこれは、vim で利用可能なゼロ幅文字で行うことができます。

\zs     Matches at any position, and sets the start of the match there: The
        next char is the first char of the whole match. |/zero-width|

したがって、あなたの試合は次のようになります。

\(.\+\n\)\{1,}\zs
于 2012-04-09T22:24:46.373 に答える