Python正则表达式:多行和非贪婪

3

我有一些像这样的文本:

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 = {

};'
]

非常感谢您的建议。

以下是关于 IT 技术的翻译内容:

5个回答

1
比赛的开头似乎是cc.,而比赛的结尾似乎是;,因此我们可以使用模式:
'cc\.[^;]+'

意思是,我们匹配cc.,然后匹配不是;的每个字符([]括起来的是字符类,^否定该类)。
您还可以使用非贪婪重复*?,但在这种情况下,我会说这是一种过度设计。正则表达式越简单,效果越好。
为了获得所需的输入,您还必须摆脱换行符。因此,我建议如下:
result = re.findall('cc\.[^;]*;', content.replace('\n', ''))

0
问题在于,你正在使用贪婪搜索。你需要使用非贪婪搜索和?运算符。
import re
print [i.replace("\n", "") for i in re.findall(r"cc\..*?{.*?}", data, re.DOTALL)]
# ['cc.Action = {}', 'cc.FiniteTimeAction = {}', 'cc.Speed = {}']

如果你不使用.*?.*{会匹配到字符串中的最后一个{。因此所有的字符串都被视为单个字符串。当你进行非贪婪匹配时,它会匹配到当前字符之后的第一个{
此外,这也可以在不使用正则表达式的情况下完成,就像这样。
print [item.replace("\n", "") for item in data.split(";") if item]
# ['cc.Action = {}', 'cc.FiniteTimeAction = {}', 'cc.Speed = {}']

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


0
正如您的标题所示,问题在于贪婪性:cc\..*=从字符串开头匹配到最后一个=
您可以通过使用懒惰量词来避免这种行为,该量词将尝试在以下字符的最早出现处停止:
cc\..*?= {.*?};

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

0

如果你基于;进行分割:

codes.split(';')

输出:

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

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

这将对你有用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接