非贪婪 XML(Python 正则表达式)中的多个匹配项
Multiple matches in non-greedy XML (Python regex)
我知道这个话题被问了很多,但我找不到问题的答案:
在附图中有许多不同的缓冲区,我希望只匹配名称中包含 "Lut" 的缓冲区(注意图像中的字符串中有 2 个匹配项)。我遇到的问题是匹配项还包含我想要的缓冲区之前的缓冲区。
我是正则表达式的新手,仍在努力学习,所以任何解释都将不胜感激。
谢谢! :)
附上绳子是为了让您感到舒适(如果需要):
<?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>
您可以使用 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
您可能想在 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
<buffer name="[^"]*Lut[^"]*">.*?<\/buffer>
见Demo
在您的正则表达式 <buffer name=".*?Lut
中,它将匹配第一个 <buffer
到第一个 Lut
。(non-greedy worked.If greedy,it will match the last Lut
)
由于您需要操作 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')
参见 IDEONE demo 显示对 XML 字符串的修改。
我知道这个话题被问了很多,但我找不到问题的答案:
在附图中有许多不同的缓冲区,我希望只匹配名称中包含 "Lut" 的缓冲区(注意图像中的字符串中有 2 个匹配项)。我遇到的问题是匹配项还包含我想要的缓冲区之前的缓冲区。
我是正则表达式的新手,仍在努力学习,所以任何解释都将不胜感激。
谢谢! :)
附上绳子是为了让您感到舒适(如果需要):
<?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>
您可以使用 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
您可能想在 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
<buffer name="[^"]*Lut[^"]*">.*?<\/buffer>
见Demo
在您的正则表达式 <buffer name=".*?Lut
中,它将匹配第一个 <buffer
到第一个 Lut
。(non-greedy worked.If greedy,it will match the last Lut
)
由于您需要操作 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()
:
print ET.dump(root) # Print updated XML
或者将更新的 DOM 写入文件(如果您正在使用文件):
tree.write('output.xml')
参见 IDEONE demo 显示对 XML 字符串的修改。