使用正则表达式解析并打印该行

时间:2014-08-28 16:23:34

标签: python regex

我有一个正则表达式,用于打印指定范围内的文件行。

例如:

my _car_(10)
skoda
audi

my home
good

my _car_(11)
benz

输出为:

(10)
skoda
audi
(11)
benz

预期:(我还需要打印行my _car_行)

my _car_(10)
skoda
audi
my _car_(11)
benz

编码:

import re
with open("in1.txt") as f:
   lines = f.read()
   m = re.findall(r'(?s)my _car_\s*(.*?)my', lines)
   for i in m:
       print i

请帮我解决,答案将不胜感激!

5 个答案:

答案 0 :(得分:1)

要包含my _car_,只需移动捕获组的左括号。

但这引发了第二个问题。您在结果中包含后续的“我的”。使用预测(?=...)来避免捕获它。

但这又引发了另一个问题。最终的车没有尾随my。所以我们也搜索字符串结尾。

最终结果:

m = re.findall(r'(?s)(my _car_\s*.*?)(?=my|$)', lines)

与正则表达式搜索无关,使用print会在项目之间引入额外的行。我们可以将print替换为os.write(),或者我们可以使用尾随,来避免额外的行。

程序:

import re
with open("in1.txt") as f:
   lines = f.read()
   m = re.findall(r'(?s)(my _car_\s*.*?)(?=my|$)', lines)
   for i in m:
       print i,

结果:

$ python in1.py 
my _car_(10)
skoda
audi

my _car_(11)
benz

答案 1 :(得分:1)

试试以下使用负前瞻和前瞻性的代码。

>>> import re
>>> s = """my _car_(10)
... skoda
... audi
... 
... my home
... good
... 
... my _car_(11)
... benz"""
>>> m = re.findall(r'my\s*_car_(?:(?!\n\n).)*(?=\n\n|$)', s, re.DOTALL)
>>> for i in m:
...     print i
... 
my _car_(10)
skoda
audi
my _car_(11)
benz

DEMO

<强>解释

  • my\s*_car_匹配字符串my后跟零个或多个空格,然后再跟着字符串_car_
  • (?:(?!\n\n).)*匹配任何字符,但不匹配\n\n零次或多次。
  • (?=\n\n|$) Lookahead断言,后面的内容必须是\n\n(即空白行)或行结束$

答案 2 :(得分:1)

您只需要扩展捕获组:

来自这个

m = re.findall(r'(?s)my _car_\s*(.*?)my', lines)

到这个

m = re.findall(r'(?s)(my _car_\s*.*?)my', lines)

应该这样做。

但是根据你的正则表达式,你必须在最后一个值之后有一个my才能捕获它。

答案 3 :(得分:1)

您可以使用积极的前瞻来实现这一目标:

(?s)(my _car_\s*.*?)(?=(?:\n{2}|\Z))

(?=(?:\n{2}|\Z))断言_car_之后的部分后跟2个换行符或字符串结尾(\Z)。

测试:

>>> import re
>>> with open('in1.txt') as f:
...     lines = f.read()
...     m = re.findall(r'(?s)(my _car_\s*.*?)(?=(?:\n{2}|\Z))', lines)
...     for i in m:
...             print i
... 
my _car_(10)
skoda
audi
my _car_(11)
benz

答案 4 :(得分:1)

正则表达式似乎没必要,请尝试:

cars = False
with open("in1.txt") as f:
    for line in map(str.strip, f):
        if line.startswith('my _car_'):
            print line
            cars = True
        elif line.startswith('my'):
            cars = False
        elif cars and line:
            print line

将输出:

my _car_(10)
skoda
audi
my _car_(11)
benz