【问题标题】:Get XML parent tag with regular expressions使用正则表达式获取 XML 父标签
【发布时间】:2015-09-30 08:46:22
【问题描述】:

我知道正则表达式并不是从 XML 文件中提取信息的最佳方式,但在这种情况下,我最好使用正则表达式,因为在我的程序结构中,它们也用于从 XML 文件中提取信息不同类型的文件(文本、程序代码等)

假设我们有以下 XML 代码:

<modules>
    <Orba_Sheepla>
        <!-- module version -->
        <version>0.9.25</version>
    </Orba_Sheepla>
</modules>

在这种情况下,我需要的是“Orba_Sheepla”。我一般需要的是&lt;version&gt; 标签(即父标签)上方的标签。同一级别的标签前后可能还有其他标签。我需要确保找到包含&lt;version&gt; 标签的标签(或者更确切地说:标签的名称)。

我尝试了不同类型的正则表达式,但我似乎无法写出正确的表达式。我可以以某种方式告诉表达式匹配以下“TAG ABC”吗?

<TAG ABC>
    anything
    <version>anything</version>
    anything
</THE VERY SAME TAG ABC>

当然,也欢迎其他解决方案!

【问题讨论】:

  • 那么,在XML语言中,需要获取版本节点父标签名,对吧?有了 XML 解析器,就真的很简单了。
  • 是的,我需要父标签,是的,使用解析器真的很容易。但是,我不能在这里使用解析器,除非为了匹配这个特定的情况而改变我的程序结构。
  • 能否请您展示您尝试过的内容。很多爱
  • 正则表达式解决方案效率低下、太难读或太“脆弱”。不,我怀疑任何人都能够正确回答您的问题。使用 XML 解析器,是一个具有前瞻性的解决方案。想象一下,您需要获得其他类似的值,然后,您将拥有一个高度可定制的解决方案。要么添加编程语言标签,要么关闭问题。
  • 这是最接近仍然有效的解决方案:'\\s+\\s+.+' 但是当然这个仅考虑空格,而不考虑其他标签或 cmets。但是,当我用 .+? 替换 \\s+ 时,它会停止返回匹配项,我不确定为什么。

标签: python regex xml


【解决方案1】:

标记上一级&lt;version&gt;
我最好使用正则表达式
我不能在这里使用解析器

您应该使用 XML 解析器!它更简单、更健壮,而且重构不需要很大的努力。使用lxml,您拥有getparent() 函数并且XPath 1.0 已完全实现。
感谢stribizhev 的推荐,这应该被注释掉

无论如何,这里有一个解决方法,适用于最简单的情况(并且在许多实际示例中都会失败)。

  • 当且仅当您的 XML 正确缩进时,您才能捕获具有较低缩进级别的下一个结束标记。

正则表达式:

(?smi)^([ \t]+)<version>.*?^(?!\1)[ \t]*</([^\s>]+)

捕获组 2 中的结束标记。
它的作用是:

  • ^([ \t]+) 捕获前面的空格
  • &lt;version&gt;你想要的标签
  • .*?^ 然后找到下一行
  • (?!\1)[ \t]* 缩进较少
  • &lt;/([^\s&gt;]+) 并捕获结束标记

代码:

import re

text = '''
<modules>
    <Orba_Sheepla>
        <!-- module version -->
        <version>0.9.25</version>
    </Orba_Sheepla>
</modules>'''

pattern = re.compile( r'^([ \t]+)<version>.*?^(?!\1)[ \t]*</([^\s>]+)', re.I | re.S | re.M)
match = pattern.search(text)

if match:
    print(match.group(2))

输出:

Orba_Sheepla

regex101 Demo ideone Demo

【讨论】:

  • 请注意:在此解决方法中,假定您的 XML 已正确缩进。这些假设在现实生活中成倍增加。使用lxml,你有getparent() 函数并且完全实现了XPath 1.0。对于这种解决方法,我被高度评价。
  • 确实,这是一种廉价的解决方法。我认为这已经足够清楚了,尽管我刚刚在答案中添加了评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多