我有一个多行字符串,希望在Python中对其应用正则表达式。有没有办法找出正则表达式在哪一行匹配?
例如,如果我使用regex
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 = []