非贪婪XML(Python正则表达式)中的多个匹配

时间:2015-09-29 08:22:39

标签: python regex xml greedy

我知道这个话题很多,但我无法找到问题的答案:

在附图中有许多不同的缓冲区,我希望只匹配具有" Lut"在他们的名字中(注意图像中的字符串中有2个匹配项)。我遇到的问题是匹配包含了我想要的缓冲区。

http://i.stack.imgur.com/p0fPS.png

我对正则表达式很陌生,并且仍在努力学习,所以任何解释都会受到赞赏。

谢谢! :)

附上字符串以方便您(如果需要):

<?xml version="1.0" encoding="utf-8"?>
<pimp xmlns:dt="urn:schemas-microsoft-com:datatypes">
    <dllPath>C:\ReplayCode\Apps\Pimp</dllPath>
    <buffers>   
    <buffer name="InputMask">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>
    <buffer name="MaskErode">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>
    <buffer name="BlablaLutBla">
            <width>256</width>
            <height>256</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>
    <buffer name="MaskClose">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>
    <buffer name="InputVis">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>3</channels>
            <type>IMG</type>
    </buffer>   
        <buffer name="AddMaskEdge">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>
    <buffer name="EdgeVis">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>3</channels>
            <type>IMG</type>
    </buffer>       
        <buffer name="GrayEdge">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>
    <buffer name="EdgeMaskMulThreshold">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>
    <buffer name="MaskMulEdge">
            <width>5120</width>
            <height>3072</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>   
    </buffers>  

我试过的正则表达式是:

<buffer name=".*?Lut.*?">.*?<\/buffer>

我期待2场比赛:

<buffer name="BlablaLutBla">
            <width>256</width>
            <height>256</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>

<buffer name="2ndLutBlabla">
            <width>256</width>
            <height>256</height>
            <data>UCHAR</data>
            <channels>1</channels>
            <type>IMG</type>
    </buffer>

4 个答案:

答案 0 :(得分:1)

您可以使用BeautifulSoup来解析您的代码。

import re
from bs4 import BeautifulSoup

input_xml = ''' some xml '''
soup = BeautifulSoup(input_xml, "lxml-xml")
print soup.find_all('buffer', attrs={"name": re.compile('Lut')})

如果您尚未安装此功能:

pip install beautifulsoup4
pip install lxml

答案 1 :(得分:1)

由于您需要操作XML文档中的数据,因此请使用XML解析器。 上面的答案已经说明了如何实例化XML树,但没有详述结构修改。

顺便说一句,如果您从字符串中实例化XML,请使用ET.fromstring

import xml.etree.ElementTree as ET
...
xml = "<<YOUR XML STRING>>" 
root = ET.fromstring(xml)

否则,从文件中读取时:

tree = ET.parse('file.xml')
root = tree.getroot()

然后,您可以使用以下替换(如果需要,您可以实际使用正则表达式,因为在这里您将不得不处理简单,未标记的文本数据):

for buffer in root.findall("buffers/buffer"): 
    if "Lut" in buffer.get("name"):
        buffer.find('width').text = "100"    # Set inner text of buffer child named 'width'
        buffer[1].text = "125"               # Set the 2nd child inner text
        buffer.set('type', 'MY_TYPE');       # Add an attribute to buffer

您可以使用.dump()打印更新的XML:

print ET.dump(root)                          # Print updated XML

或者将更新的DOM写入文件(如果您正在处理文件):

tree.write('output.xml')

请参阅显示XML字符串修改的IDEONE demo

答案 2 :(得分:0)

您可能希望在python中使用xml解析,这很容易:

import xml.etree.ElementTree as ET
tree = ET.parse(xml)
for buffer in tree.findall("buffers/buffer"): 
    if "Lut" in buffer.get("name"):
        # do your stuff
        pass

答案 3 :(得分:0)

<buffer name="[^"]*Lut[^"]*">.*?<\/buffer>

请参阅Demo

在正则表达式<buffer name=".*?Lut中,它将从第一个<buffer到第一个Lut匹配。(non-greedy worked.If greedy,it will match the last Lut