匹配任意分割多行的字符串

时间:2012-05-05 06:21:35

标签: python regex multiline

在正则表达式中是否有一种方法可以匹配任意分割为多行的字符串 - 比如我们在文件中有以下格式:

msgid "This is "
"an example string"
msgstr "..."

msgid "This is an example string"
msgstr "..."

msgid ""
"This is an " 
"example" 
" string"
msgstr "..."

msgid "This is " 
"an unmatching string" 
msgstr "..."

所以我们希望有一个匹配所有示例字符串的模式,即:匹配字符串,无论它是如何跨行分割的。请注意,我们在示例中显示的特定字符串之后,而不仅仅是任何字符串。所以在这种情况下,我们希望匹配字符串"This is an example string"

当然我们可以轻松地连接字符串然后应用匹配,但让我想知道这是否可行。我正在谈论 Python 正则表达式,但一般的答案是可以的。

2 个答案:

答案 0 :(得分:4)

你想要匹配一系列单词吗?如果是这样,你可以查找中间只有空格(\ s)的单词,因为\ s匹配换行符和空格。

import re

search_for = "This is an example string"
search_for_re = r"\b" + r"\s+".join(search_for.split()) + r"\b"
pattern = re.compile(search_for_re)
match = lambda s: pattern.match(s) is not None

s = "This is an example string"
print match(s), ":", repr(s)

s = "This is an \n example string"
print match(s), ":", repr(s)

s = "This is \n an unmatching string"
print match(s), ":", repr(s)

打印:

True : 'This is an example string'
True : 'This is an \n example string'
False : 'This is \n an unmatching string'

答案 1 :(得分:0)

这有点棘手,因为需要在每一行上引用,以及空行的容差。这是一个与您正确发布的文件匹配的正则表达式:

'(""\n)*"This(( "\n(""\n)*")|("\n(""\n)*" )| )is(( "\n(""\n)*")|("\n(""\n)*" )| )an(( "\n(""\n)*")|("\n(""\n)*" )| )example(( "\n(""\n)*")|("\n(""\n)*" )| )string"'

这有点令人困惑,但它只是你要匹配的字符串,但它始于:

(""\n)*"

并将每个单词之间的空格替换为:

(( "\n(""\n)*")|("\n(""\n)*" )| )

在每个单词之后检查三种不同的可能性,或者是“空格,引号,换行符,(无限数量的空字符串)引用”,或者相同的序列,但更多的空间到达结尾,或者只是空格。 / p>

更简单的方法就是编写一个小函数来接受你想要匹配的字符串并返回与之匹配的正则表达式:

def getregex(string):
    return '(""\n)*"' + string.replace(" ", '(( "\n(""\n)*")|("\n(""\n)*" )| )') + '"'

所以,如果你有一个名为“filestring”的字符串中的文件,你会得到这样的匹配:

import re

def getregex(string):
    return '(""\n)*"' + string.replace(" ", '(( "\n(""\n)*")|("\n(""\n)*" )| )') + '"'

matcher = re.compile(getregex("This is an example string"))

for i in matcher.finditer(filestring):
    print i.group(0), "\n"

>>> "This is "
    "an example string"

    "This is an example string"

    ""
    "This is an "
    "example"
    " string"

这个正则表达式没有考虑第三个msgid中“示例”之后的空间,但我认为这是由机器生成的,这是一个错误。