如何匹配多行字符串中的行首和结尾

时间:2018-11-22 09:09:46

标签: python regex python-3.x

我想在多行字符串中匹配整行(此代码是检查正确输出格式的单元测试的一部分)。

Python 3.5.2 (default, Nov 12 2018, 13:43:14) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.match(r".*score = 0\.59.*", r"score = 0.65\nscore = 0.59\nscore = 1.0", re.MULTILINE)
<_sre.SRE_Match object; span=(0, 39), match='score = 0.65\\nscore = 0.59\\nscore = 1.0'>

这很好,我可以匹配多行字符串中的任何内容。但是,我想确保我匹配整条线。文档说,^$在使用re.MULTILINE时应与行的开头和结尾匹配。但是,这对我不起作用:

>>> re.match(r".*^score = 0\.59$.*", r"score = 0.65\nscore = 0.59\nscore = 1.0", re.MULTILINE)
>>> 

这是我做过的一些实验:

>>> import os
>>> re.match(r".*^score = 0\.59$.*", "score = 0.65{}score = 0.59{}score = 1.0".format(os.linesep, os.linesep), re.MULTILINE)
>>>
>>> re.match(r".*^score = 0\.65$.*", "score = 0.65{}score = 0.59{}score = 1.0".format(os.linesep, os.linesep), re.MULTILINE)
<_sre.SRE_Match object; span=(0, 12), match='score = 0.65'>
>>> re.match(r".*^score = 0\.65$.*", r"score = 0.65\nscore = 0.59\nscore = 1.0", re.MULTILINE)
>>> 

我想我缺少了一些相当简单的东西,但无法弄清楚。

3 个答案:

答案 0 :(得分:3)

问题是,由于您正在使用原始字符串作为字符串,因此\n被视为……好\,然后是n。正则表达式会在模式中显示\n ,但在输入字符串中不会。

此外,即使在那里不重要,也请始终使用flags=关键字,因为某些正则表达式函数具有额外的count参数,并且可能导致错误。

像这样:

re.match(r".*^score = 0\.65$.*", "score = 0.65\nscore = 0.59\nscore = 1.0", flags=re.MULTILINE)
<_sre.SRE_Match object; span=(0, 12), match='score = 0.65'>

正如我在评论中所指出的,.*需要re.DOTALL才能匹配换行符

>>> re.match(r".*^score = \d+\.\d+$.*", "score = 0.65\nscore = 0.59\nscore = 1.0", re.MULTILINE|re.DOTALL)
<_sre.SRE_Match object; span=(0, 37), match='score = 0.65\nscore = 0.59\nscore = 1.0'>

(如Python regex, matching pattern over multiple lines.. why isn't this working?How do I match any character across multiple lines in a regular expression?中所述,如果不是原始字符串位,则此可以重复)

(对不起,我的浮点正则表达式可能有点弱,您可以在附近找到更好的东西)

答案 1 :(得分:2)

您需要与非原始字符串匹配,并且使用DOTALL模式:

print re.match(r".*^score = 0\.59$.*", "score = 0.65\nscore = 0.59\nscore = 1.0",
    re.MULTILINE|re.DOTALL)

<_sre.SRE_Match object at 0x7fd2426d0648>

答案 2 :(得分:1)

您问题的真正答案是,您仅混淆了matchsearch

>>> import os, re
>>> print(re.match(r".*^score = 0\.59$.*", "score = 0.65\nscore = 0.59\nscore = 1.0", flags=re.MULTILINE))
None
>>> print(re.search(r".*^score = 0\.59$.*", "score = 0.65\nscore = 0.59\nscore = 1.0", flags=re.MULTILINE))
<_sre.SRE_Match object; span=(13, 25), match='score = 0.59'>
>>> 

这就是为什么您的一个非原始示例有效而另一个示例无效的原因。