web-dev-qa-db-ja.com

vim regexは、複数の連続するスペースを1つのスペースのみに置き換えます

私はよく、Wordの区切り文字として空白の可変量を含むテキストファイルを使用します(Wordのようなテキストプロセッサは、特定のフォントの文字のサイズが異なるために空白の量を均等に分散し、プレーンテキストとして保存)。

可変長の空白のこれらのシーケンスを単一のスペースに置き換えるプロセスを自動化したいと思います。私は正規表現でそれができると思いますが、段落の先頭にも空白があります(通常は4つですが、常にではありません)、変更しないようにしたいので、基本的には正規表現も先頭の空白に触れないでください複雑さが増します。

私はvimを使用しているので、vim regex方言の正規表現は、これが実行可能であれば非常に便利です。

私の現在の進捗状況は次のとおりです。

:%s/ \+/ /g

しかし、それは正しく動作しません。

また、テキスト行を1つずつ解析し、各行を1文字ずつ処理し、最初の行以降の空白をスキップできるvimスクリプトを作成することも検討していますが、これはやり過ぎだと感じています。

64
jedi_coder

プラグマティズムの利益のために、私はそれを3段階のプロセスとして行う傾向があります。

:g/^    /s//XYZZYPARA/g
:g/ \+/s// /g
:g/^XYZZYPARA/s//    /g

私はより良い方法があるかもしれないことを疑いません(おそらくマクロや純粋な正規表現の方法を使用するかもしれません)が、私は通常急いでいるときにこれが動作することを発見します。もちろん、XYZZYPARAで始まる行がある場合は、文字列を調整する必要があります:-)

回すのに十分です:

    This is a new paragraph
spanning       two lines.
    And    so    is   this but on one line.

に:

    This is a new paragraph
spanning two lines. 
    And so is this but on one line.

脇:なぜ私が:g の代わりに :s、それはほとんど習慣です。 :gは何でもできます:sできます。実際には、選択した行で任意コマンドを実行する方法です。この場合、実行するコマンドはたまたまsであるため、実質的な違いはありませんが、viパワーユーザーになりたい場合は、:g ある時点で。

39
paxdiablo

これは2つ以上のスペースを置き換えます

s/ \{2,}/ /g

または、バージョンの\+の前に余分なスペースを追加できます

s/  \+/ /g
109
mikerobi

これはトリックを行います:

%s![^ ]\zs  \+! !g

\zsおよび\zeメタシーケンスを使用することにより、他の正規表現の方言よりも多くの置換をVimで簡単に行うことができます。彼らがやることは、マッチの一部を最終結果から除外することです。シーケンスの前の部分(\zs、“ s here”の場合は“ s”)または後の部分(\ze、“ e 「ここで終了」を意味します)。この場合、パターンは最初にスペース以外の1文字([^ ])に一致する必要がありますが、次の\zsは、最終的な一致結果(置き換えられるもの)が始まることを示しますその文字。

行頭の空白の前にスペース以外の文字を使用する方法がないため、パターンと一致しないため、置換は置換されません。シンプル。

59

ここにはたくさんの良い答えがあります(特にアリストテレスの:\zs\zeは学ぶ価値があります)。完全を期すために、ネガティブな後読みアサーションでこれを行うこともできます。

:%s/\(^ *\)\@<! \{2,}/ /g

これは、「行の先頭にゼロ個以上のスペースが続く」が前にない2つ以上のスペース(' \{2,}')を見つけることを意味します。バックスラッシュの数を減らしたい場合は、これも実行できます。

:%s/\v(^ *)@<! {2,}/ /g

しかし、それはあなたに2人のキャラクターを救うだけです!冗長な変更(つまり、単一のスペースを単一のスペースに変更する)の負荷を気にしない場合は、' +'の代わりに' {2,}'を使用することもできます。

ネガティブな後読みを使用して、スペース以外の単一の文字をチェックすることもできます。

:%s/\S\@<!\s\+/ /g

これは(スペースとタブを同じように扱い、入力を少し節約するためにアリストテレスを少し変更したバージョン)とほぼ同じです:

:%s/\S\zs \+/ /g

見る:

:help \zs
:help \ze
:help \@<!
:help zero-width
:help \v

そして(すべて読んでください!):

:help pattern.txt
7
DrAl

私はこのバージョンが好きです-アリストテレス・パガルツィスの先読みバージョンに似ていますが、理解しやすいと思います。 (おそらく、\ zsに不慣れなだけです)

s/\([^ ]\) \+/\1 /g

またはすべての空白について

s/\(\S\)\s\+/\1 /g

私はそれを「スペース以外の何かのすべての出現を、何かと単一のスペースで複数のスペースが続く」と読みました。

2

回答済み。しかし、とにかく私の仕事の流れを投げたいと思います。

%s/  / /g
@:@:@:@:@:@:@:@:@:@:@:@:(repeat till clean)

覚えやすい高速かつシンプル。上記のはるかにエレガントなソリューションがあります。しかし、ちょうど私の.02。

2
wom

これは機能しますか?

%s/\([^ ]\)  */\1 /g
2
frogstarr78