19

假设您有一些看起来像这样的行

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

等等。缩进是用空格完成的,每个缩进是两个空格。

您想将每个缩进更改为三个空格。简单的正则表达式

s/ {2}/   /g

对您不起作用,因为这会改变一些非缩进空格;在这种情况下,它将之前的两个空格更改// Some silly comment为三个空格,这是不希望的。(如果在行尾对齐表格或注释,情况会变得更糟。)

你不能简单地使用

/^( {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

这是另一个,而不是利用\G支持 NET、PCRE(C、PHP、R…)、Java、Perl 和 Ruby

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

\G[...] 可以在以下两个位置之一进行匹配:
✽ 字符串的开头,
✽ 紧跟上一个匹配结尾的位置。

来源: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 回答