我有一个多行字符串,想在 Python 中对其应用正则表达式。有没有办法找出正则表达式匹配的行?
例如,如果我使用正则表达式
regex = re.compile("(?<=i)s")
在弦上
s = """This
is
a multiline
string"""
我怎样才能找到那条线0
并1
匹配?regex.findall(s)
给了我所有匹配项的列表,但它没有告诉我这些匹配项在哪一行。
如果你使用regex.finditer
你可以得到这样的行号:
regex = re.compile("(?<=i)s")
s = """This
is
a multiline
string"""
for match in regex.finditer(s):
lineno = s.count('\n', 0, match.start())
...
您可以使用enumerate()
获取行号:
>>> regex = re.compile("(?<=i)s")
>>> results = []
>>> for lineno, line in enumerate(s.split("\n")):
... if regex.search(line):
... results.append((lineno, line))
...
>>> results
[(0, 'This'), (1, 'is')]
当然,如果您自己不需要该行的内容,只需执行results.append(lineno)
.
一种简单的方法是交替匹配换行符:
lineno=1
for m in re.findall(r'\n|(?<=i)s', s):
if m != '\n': print lineno, m
else : lineno += 1
如果使用re.MULTILINE
,插入符号 ( ^
) 将匹配字符串的开头和行的开头。稍微更改您的正则表达式,将为您提供所有行的列表,其中包含您不匹配的空字符串:
>>> regex = re.compile("(^.*(?<=i)s|^)", re.MULTILINE)
>>> regex.findall(s)
['This', 'is', '', '']
然后行号是索引加上字符串不为空的列表之一:
>>> [(i + 1, j) for (i, j) in enumerate(regex.findall(s)) if j != '']
[(1, 'This'), (2, 'is')]
对于您在评论中提出的第二个问题,
您可以使用re
和StringIO
import re
from StringIO import StringIO
s = """This
is
a multiline
string.
This is a line with several "is\""""
print s
rgx = re.compile("(?<=i)s")
def graou(s):
sl = 0
for i,line in enumerate(StringIO(s)):
tu = tuple(sl+m.start() for m in rgx.finditer(line))
if tu: yield (i,tu)
sl += len(line)
print [x for x in graou(s) if x[1]]
要么re
只有(我更喜欢):
import re
s = """This
is
a multiline
string.
This is a line with several "is\""""
print s
rgx = re.compile('$|(?<=i)s',re.MULTILINE)
def graou(s):
i,li = 0,[]
for m in rgx.finditer(s):
if m.group()!='':
li.append(m.start())
elif li:
yield((i,tuple(li)))
i += 1
li = []