【问题标题】:Python findall and regular expressionsPython findall 和正则表达式
【发布时间】:2011-07-18 13:58:57
【问题描述】:

我正在解析一个包含两种不同类型行的 xml 文件(下面称为 xml):

1. <line a="a1" b="b1" c="c1">
2. <line a="a2" c="c2">

我试图只从第二种类型中提取 a2 和 c2,但是这个正则表达式也捕获第一种类型:

>>> list = re.findall('<line a="(.*)" c="(.*)">', xml)
>>> print(list)
[('a1" b="b1', 'c1'), ('a2', 'c2')]

如何只捕获第二种类型?

【问题讨论】:

  • 为什么要使用正则表达式来解析 XML?它们并不完全正常...例如,您是否查看过 ElementTree 库?

标签: python regex findall


【解决方案1】:

使用像ElementTree 这样的适当的 XML 解析库,而不是诉诸正则表达式,这更有意义。例如:

>>> xmlstr = """\
... <root>
...   <line a="a1" b="b1" c="c1"></line>
...   <line a="a2" c="c2"></line>
... </root>
... """
>>> import xml.etree.ElementTree as ET
>>> root = ET.XML(xmlstr)
>>> root.findall('./line')
[<Element 'line' at 0x226db70>, <Element 'line' at 0x226de48>]
>>> filtered = [line for line in root.findall('./line') if line.get('b') is None]
>>> for line in filtered:
...     print ET.tostring(line)
...
<line a="a2" c="c2" />

>>>

【讨论】:

  • 我通过 timeit 运行它,正则表达式解决方案大约快 50 倍。所以如果速度很重要,你知道你在找什么,你知道你会得到什么样的 xml,那么使用正则表达式可能是更好的选择
  • 以可维护性和可读性为代价。还有 cElementTree 实现了相同的 API,但在原生 C 中作为扩展模块。但是,如果速度对您来说非常重要,为什么首先要使用 Python? ;-)
  • 也感谢您提供此方法。它对我正在处理的其他一些任务很有用。
【解决方案2】:

* 操作符默认是贪婪的。尝试 ([^"]*) 而不是 (.*)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-13
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多