2012-05-05 41 views
4

是否有正则表达式的方式,以匹配任意分隔成了多行字符串 - 说我们有一个文件中的格式如下:匹配的字符串的任意分割多行

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正则表达式的,但一般的答案是好的。

回答

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' 
+0

是的问题没有指定是否分裂是在字边界或字符边界。但类似的概念将适用于两者。 –

+0

这种方法非常聪明,但我可以看到它的一个问题:如果字符串包含元字符,那将会破坏我们的模式。我不确定如何处理。 –

+0

这就是为什么我问你是否打算搜索一系列正常的单词。如果你想搜索更复杂的结构,你必须以不同的方式构造正则表达式。但是对问题的回答很清楚:“use \ s”。如何处理任意输入作为搜索模式是一个完全不同的问题。您可以简单地允许元字符或转义它们,或提醒用户不要使用它们等。 – pwuertz

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)*")|) 

其中每个字后检查了三种不同的可能性,无论是“空间,报价,换行,(空字符串的数量不受限制)报价”,或相同的本身但更多的空间到最后,或者只是一个空间。

更简单的方法来得到这个工作是写,将带你试图匹配并返回,将匹配它的正则表达式的字符串中的一个小功能:

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“榜样”后的空间,但我认为这是由机器产生的,这是一个错误。