Python: consecutive lines between matches similar to awk
-
多行字符串
string (已从文件file 中读取) -
两种模式
pattern1 和pattern2 将分别匹配string 中仅一行的子字符串。 这些行将称为line1和line2。
模式是正则表达式模式,但是如果可以简化的话,我可以更改其格式。
已搜寻
我正在寻找一种方法来获取python中line1和line2之间的所有行(我们可以安全地假设line1在line2之前)。
当然,这可以通过
1 | awk '/pattern1/,/pattern2/' file |
例:
文件:
1 2 3 4 5 6 | aaa aa a bbb bb b ccc cc c ddd dd d eee ee e fff ff f |
模式1:
pattern2:
期望的结果:
1 2 3 | bbb bb b ccc cc c ddd dd d |
在
要在Python中执行范围运算符,请编写一个类来跟踪对
给定示例文件,您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import re class FlipFlop: ''' Class to imitate the bahavior of /start/, /end/ flip flop in awk ''' def __init__(self, start_pattern, end_pattern): self.patterns = start_pattern, end_pattern self.state = False def __call__(self, st): ms=[e.search(st) for e in self.patterns] if all(m for m in ms): self.state = False return True rtr=True if self.state else False if ms[self.state]: self.state = not self.state return self.state or rtr with open('/tmp/file') as f: ff=FlipFlop(re.compile('b bb'), re.compile('d dd')) print ''.join(line if ff(line) else"" for line in f) |
印刷品:
1 2 3 | bbb bb b ccc cc c ddd dd d |
这样可以保留逐行读取的文件,并具有其他语言中
1 2 | ''.join(line+"\ " if ff(line) else"" for line in s.splitlines()) |
习惯上,在awk中,使用标志可以获得与触发器相同的结果:
1 | $ awk '/b bb/{flag=1} flag{print $0} /d dd/{flag=0}' file |
您也可以在Python中复制它(使用更多单词):
1 2 3 4 5 6 7 8 9 | flag=False with open('file') as f: for line in f: if re.search(r'b bb', line): flag=True if flag: print(line.rstrip()) if re.search(r'd dd', line): flag=False |
也可以与内存字符串一起使用。
或者,您可以使用多行正则表达式:
1 2 | with open('/tmp/file') as f: print ''.join(re.findall(r'^.*b bb[\\s\\S]*d dd.*$', f.read(), re.M)) |
演示与说明
但这需要将整个文件读入内存。由于您声明该字符串已被读入内存,因此在这种情况下这可能是最简单的:
1 | ''.join(re.findall(r'^.*b bb[\\s\\S]*d dd.*$', s, re.M)) |
使用re.DOTALL匹配包括换行符在内的所有内容。然后插入开始模式和结束模式:
1 | re.search( '[\\w ]*b bb.*?d dd[ \\w]*', string, re.DOTALL).group(0) |
注意:(1)
1 | re.search( '[\\w ]*b bb.*?d dd[ \\w]*', open('file').read(), re.DOTALL).group(0) |
使用
1 2 3 4 5 6 7 8 | >>> print(a) aaa aa a bbb bb b ccc cc c ddd dd d eee ee e fff ff f |
预期结果:
1 2 3 4 5 6 | >>> print(re.search('^.*bb b$\ ((:?.+\ )+)^.*dd d$',a, re.M).group()) bbb bb b ccc cc c ddd dd d |
或仅附上文字:
1 2 3 4 | >>> print(re.search('^.*bb b$\ ((:?.+\ )+)^.*dd d$',a, re.M).group(1)) ccc cc c |