19

このような行があるとしましょう

1  int some_function() {
2    int x = 3;  // Some silly comment

等々。インデントはスペースで行われ、各インデントは2つのスペースです。

各インデントを3つのスペースに変更します。単純な正規表現

s/ {2}/   /g

インデントされていないスペースが変更されるため、機能しません。この場合、前の2つのスペース// Some silly commentを3つのスペースに変更しますが、これは望ましくありません。(行の最後にテーブルまたはコメントが配置されている場合、これはさらに悪化します。)

単純に使用することはできません

/^( {2})+/

何に置き換えますか?+正規表現でaが何回一致したかを簡単に知る方法がわからないため、挿入する変更されたインデントの数がわかりません。

いつでも行ごとにインデントを切り取り、測定し、新しいインデント文字列を作成して、それを行に追加することができますが、正規表現があれば、はるかに簡単になります。

上記のようにインデントレベルを置き換える正規表現はありますか?

4

4 に答える 4

11

一部の正規表現フレーバーでは、後読みを使用できます。

s/(?<=^ *)  /   /g

他のすべてのフレーバーでは、文字列を逆にして、先読み(すべてのフレーバーがサポート)を使用して、もう一度逆にすることができます。

 s/  (?= *$)/   /g
于 2012-10-09T20:57:05.337 に答える
9

インデントのスペースの量を半分にする必要がありました。つまり、インデントが4スペースの場合、2スペースに変更する必要がありました。正規表現を思い付くことができませんでした。しかし、ありがたいことに、他の誰かがしました:

//search for
^( +)\1 
//replace with (or \1, in some programs, like geany)
$1 

ソースから: "^( +)\1は、行の先頭にあるゼロ以外の長さのスペースのシーケンスと、それに続く同じスペースのシーケンスを意味します。\1パターン内と$1置換内は、どちらもスペースの初期シーケンスへの逆参照です。結果:インデントが半分になりました。」

于 2015-06-22T19:09:13.847 に答える
8

代わりに、NET、PCRE(C、PHP、R…)、Java、Perl、Rubyをサポートする\G別のものを使用します。

s/(^|\G) {2}/   /g

\G[...]次の2つの位置のいずれかで一致できます。✽
文字列の先頭、
✽前の一致の終了の直後の位置。

出典: http: //www.rexegg.com/regex-anchors.html#G

前の一致の終わりの直後の位置で一致する機能を利用します。この場合、行の先頭に2つの空白が続きます(または前述のルールに従った前の一致)。

例を参照してください:https ://regex101.com/r/qY6dS0/1

于 2015-05-18T13:36:19.050 に答える
0

あなたはこれを試すことができます:

^(\s{2})|((?<=\n(\s)+))(\s{2})

壊す:

^(\s{2})  = Searches for two spaces at the beginning of the line
((?<=\n(\s)+))(\s{2}) = Searches for two spaces
    but only if a new line followed by any number of spaces is in front of it.
    (This prevents two spaces within the line being replaced)

私はperlに完全には精通していませんが、これが機能するかどうかを確認するためにこれを試してみます。

s/^(\s{2})|((?<=\n(\s)+))(\s{2})/\s\s\s/g

@Janが指摘したように、他の非スペース空白文字が存在する可能性があります。それが問題である場合は、これを試してください。

s/^( {2})|((?<=\n( )+))( {2})/   /g
于 2012-10-09T21:06:37.113 に答える