python正则表达式:多线和非贪婪

时间:2014-04-03 09:38:26

标签: python regex

我有一些这样的文字:

cc.Action = {
};

cc.FiniteTimeAction = {

};

cc.Speed = {

};

我想要的结果(列表)是:

['cc.Action = {}', 'cc.FiniteTimeAction = {}', 'cc.Speed = {}']

以下是我的尝试:

input = codecs.open(self.input_file, "r", "utf-8")
content = input.read()
result = re.findall('cc\..*= {.*};', content, re.S)
for r in result:
    print r
    print '---------------'

结果是:

[
'cc.Action = {
};

cc.FiniteTimeAction = {

};

cc.Speed = {

};'
]

任何建议都将不胜感激,谢谢:)

5 个答案:

答案 0 :(得分:1)

匹配的开头似乎是cc.,匹配的结尾似乎是;所以我们可以使用模式:

'cc\.[^;]+'

意思是,我们匹配cc.然后匹配不是;的每个字符([]包含字符类,^否定该类。)

你也可以使用非贪婪的重复*?,但在这种情况下,我会说它有点矫枉过正。正则表达式越简单越好。

要获得所需的输入,您还必须摆脱换行符。我会一起提议:

result = re.findall('cc\.[^;]*;', content.replace('\n', ''))

答案 1 :(得分:0)

问题是,你正在使用贪婪的搜索。您需要使用?运算符

进行非贪婪搜索
import re
print [i.replace("\n", "") for i in re.findall(r"cc\..*?{.*?}", data, re.DOTALL)]
# ['cc.Action = {}', 'cc.FiniteTimeAction = {}', 'cc.Speed = {}']

如果您不使用.*?.*{将匹配字符串中的最后一个{。因此,所有字符串都被视为单个字符串。当你进行非贪婪的匹配时,它会匹配到当前角色的第一个{

此外,这可以在不使用RegEx的情况下完成,如此

print [item.replace("\n", "") for item in data.split(";") if item]
# ['cc.Action = {}', 'cc.FiniteTimeAction = {}', 'cc.Speed = {}']

根据;分割字符串,如果当前字符串不为空,则用空字符串替换所有\n(换行符)。

答案 2 :(得分:0)

正如您的标题所示,问题是贪婪:cc\..*=匹配从字符串的开头到 last =

您可以使用延迟量词来避免此行为,该量词将尝试在最早出现的下一个字符时停止:

cc\..*?= {.*?};

在这里演示:http://regex101.com/r/oL4yG7

答案 3 :(得分:0)

如果您根据;进行拆分:

codes.split(';')

输出:

['cc.Action = {}', ' cc.FiniteTimeAction = {}', 'cc.Speed = {}', '']

答案 4 :(得分:0)

>>> 'cc.Action = {\n};\n\ncc.FiniteTimeAction = {\n\n};\n\ncc.Speed = {\n\n};'.replace('\n','').split(";")
['cc.Action = {}', 'cc.FiniteTimeAction = {}', 'cc.Speed = {}', '']

这对你有用