关于sublimetext3:如何使用Regex捕获和替换包含单独模式的行上的所有模式

How to capture and replace all patterns on a line containing a separate pattern with Regex

我正在尝试设置一个正则表达式,该表达式将允许我用制表符替换2个空格,但只能在包含特定模式的行上使用。

1
2
foo: here  is  some  sample  text
bar: here  is  some  sample  text

在上面的示例中,我想用制表符替换2个空格的任何组,但仅在包含" bar "的行上:

1
2
foo: here  is  some  sample  text
bar: here    is    some    sample    text

我得到的最接近的数字一直在使用:

1
2
Find: ^(\\s.*)(bar)(.*)  (.*)
Replace: \\1\\2\\3\\t\\4

但是,这一次一次只能替换一组两个空格,因此我得出以下结论:

1
2
foo: here  is  some  sample  text
bar: here  is  some  sample    text

我可以再执行3次替换并获得所需的结果,但是我正在处理可能包含数百个这些序列的文本文件。

我正在使用Sublime Text,但我很确定它的正则表达式使用了PCRE。


这也很好

1
(?m-s)(?:^(?=.*\\bbar\\b)|(?!^)\\G).*?\\K[ ]{2}

https://regex101.com/r/vnM649/1
或者
https://regex101.com/r/vnM649/2

解释

1
2
3
4
5
6
7
8
9
10
11
 (?m-s)               # Multi-line mode, not Dot-All mode
 (?:
      ^                    # Only test at BOL for 'bar'
      (?= .* \\b bar \\b )
   |                     # or,
      (?! ^ )              # Not BOL, must have found 2 spaces in this line before
      \\G                   # Start where last 2 spaces left off
 )
 .*?                  # Minimal any character (except newline)
 \\K                   # Ignore anything that matched up to this point
 [ ]{2}               # 2 spaces to replace with a \\t

possible to translate this to work with Python?

是的。

\\G构造提供了完成所有操作的能力
在一次通过正则表达式中。 Python regex模块支持它,
但不是re模块。如果使用re模块,则需要
只需2步即可完成操作。

首先是匹配bar所在的行
然后将其传递给回调以替换所有双精度型
到制表符的空格,然后将其作为替换项返回
回到呼叫者。

示例Python代码:

https://rextester.com/AYM96859

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 #python 2.7.12

 import re

 def replcall(m):
     contents = m.group(1)
     return re.sub( r'[ ]{2}',"\\t", contents )

 str = (
 r'foo: here  is  some  sample  text' +"\
"
 r'bar: here    is    some    sample    text' +"\
"
 )

 newstr = re.sub( r'(?m)(^(?=.*\\bbar\\b)(?=.*[ ]{2}).*)', replcall, str )

 print newstr

获取行的正则表达式,展开:

1
2
3
4
5
6
7
 (?m)
 (                             # (1 start)
      ^
      (?= .* \\b bar \\b )
      (?= .* [ ]{2} )
      .*
 )                             # (1 end)


这将起作用:

1
2
Find: (^(?!.*bar).*)|  
Replace: \\1\\t

(请注意" find"正则表达式末尾的2个空格),但它将在foo行的末尾添加一个制表符。

请参阅此处的PCRE演示。