如何在匹配的组中捕获字符串的多个出现位置(嵌套的正则表达式)

时间:2017-09-06 12:59:25

标签: regex python-3.x

我想用(当然)嵌套结构解析XML文件:

<begin>
<Paket>
<Name>Kwertzu</Name>
<Funktion><Kurzbezeichnung>Glubub</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
<Funktion><Kurzbezeichnung>Gwertzu</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
<Funktion><Kurzbezeichnung>Klu_gulbi</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
<Funktion><Kurzbezeichnung>QWER_TZU_ewrt</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
<Funktion><Kurzbezeichnung>MERM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
</Paket>
<Paket>
<Name>KULU</Name>
<Funktion><Kurzbezeichnung>GLM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
<Funktion><Kurzbezeichnung>IWUS_asd</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
<Funktion><Kurzbezeichnung>PLUM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
</Paket>
</begin>

我有兴趣获取...的名称和所有内容

我尝试过: r'<Paket>\s*<Name>(\w*)</Name>.*?(?:<Kurzbezeichnung>(.*?)</Kurzbezeichnung>.*?)*</Paket>', re.S 这只会返回最后一个条目,但...... 有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

我可以看到为什么XML解析很难,带我一点!以下是您想要的工作示例:

import xml.etree.ElementTree as ET

def main ():
    data = '''<begin>
    <Paket>
    <Name>Kwertzu</Name>
    <Funktion><Kurzbezeichnung>Glubub</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    <Funktion><Kurzbezeichnung>Gwertzu</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    <Funktion><Kurzbezeichnung>Klu_gulbi</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    <Funktion><Kurzbezeichnung>QWER_TZU_ewrt</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    <Funktion><Kurzbezeichnung>MERM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    </Paket>
    <Paket>
    <Name>KULU</Name>
    <Funktion><Kurzbezeichnung>GLM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    <Funktion><Kurzbezeichnung>IWUS_asd</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    <Funktion><Kurzbezeichnung>PLUM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
    </Paket>
    </begin>'''

    root = ET.fromstring(data)
    for child1 in root:
        for child2 in child1:
            if child2.tag == "Name":
                print (child2.text)
            if child2.tag == "Funktion":
                for child3 in child2:
                    if child3.tag == "Kurzbezeichnung":
                        print (child3.text)

main ()

这将输出:

Kwertzu
Glubub
Gwertzu
Klu_gulbi
QWER_TZU_ewrt
MERM
KULU
GLM
IWUS_asd
PLUM

基本上创建一个可以迭代的对象。关键点是:

使用.tag - 这就是节点

使用.text - 这是节点中的值

希望这有帮助!

答案 1 :(得分:0)

由于我的例子太简单了,而且真实的&#34; XML看起来更像是这样:

<MyList xmlns="http://www.example.com">
  <FirstTag>
    <Name>Group</Name>
    <SecondTag>
      <Name>DCT23335.7</Name>
      <ThirdTag>
        <Name>AnotherName</Name>
        <Paket>
            <Name>Kwertzu</Name>
            <Funktion><Kurzbezeichnung>Glubub</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
            <Funktion><Kurzbezeichnung>Gwertzu</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
            <Funktion><Kurzbezeichnung>Klu_gulbi</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
            <Funktion><Kurzbezeichnung>QWER_TZU_ewrt</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
            <Funktion><Kurzbezeichnung>MERM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
        </Paket>
        <Paket>
            <Name>KULU</Name>
            <Funktion><Kurzbezeichnung>GLM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
            <Funktion><Kurzbezeichnung>IWUS_asd</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
            <Funktion><Kurzbezeichnung>PLUM</Kurzbezeichnung><OtherTag>content</OtherTag></Funktion>
        </Paket>
      </ThirdTag>
    </SecondTag>
  </FirstTag>
</MyList>

因此,您必须通过编码来对抗命名空间和XML的疯狂嵌套特性:

root = ET.fromstring(data)

ns = {'ns': re.findall(r'<MyList xmlns="([^"]*)"', data)[0]}
dict_elements = {}
outer_elements = root.find('ns:FirstTag', ns).find('ns:SecondTag', ns).find('ns:ThirdTag', ns).findall('ns:Paket', ns)

for outer_element in outer_elements:
    outer_element_name = outer_element.find('ns:Name', ns).text
    inner_elements = outer_element.findall('ns:Funktion', ns)
    for inner_element in inner_elements:
        dict_elements[inner_element.find('ns:Kurzbezeichnung', ns).text] = outer_element_name

这可以工作但是(即使没有命名空间字符串的正则表达式查找)几乎是我之前使用的嵌套正则表达式搜索的两倍。 好像我还不是ElementTree的粉丝...... 再次感谢帮助我完成工作!