我有以下文字:
<vehicle id="1292442" depart="26060.00">
<route edges="24449167#2 27659684#1 24686876#1"/>
我想将车辆 ID 和路线边缘中的每个项目放在元组变量中
tuples = re.findall(r'<vehicle\sid="(.+?)"\s+(<route\sedges="(.+)"/>', text)
如何忽略标签之间的空格?
\s+
不这样做。
我有以下文字:
<vehicle id="1292442" depart="26060.00">
<route edges="24449167#2 27659684#1 24686876#1"/>
我想将车辆 ID 和路线边缘中的每个项目放在元组变量中
tuples = re.findall(r'<vehicle\sid="(.+?)"\s+(<route\sedges="(.+)"/>', text)
如何忽略标签之间的空格?
\s+
不这样做。
那是 XML。您应该使用 XML 解析器,而不是正则表达式。
也就是说,为什么不只是strip()
之后多余的空白呢?
使用像lxml这样的 XML 解析器。这将使您可以轻松访问所需的元素及其属性。对于一个属性中不同的路由边,使用split()
字符串的方法:
In [1]: edges="24449167#2 27659684#1 24686876#1"
In [2]: edges.split()
Out[2]: ['24449167#2', '27659684#1', '24686876#1']
以下面向流的 XML 解析 hack 仅使用 Python 标准库。
对不起,回答太长了:因为解析 XML 太让人麻木了,所以我更喜欢找到“创造性地”做它的方法:)
以下代码将结果元组累积到一个列表中。但是由于协程可以以任意方式链接,您可以将其演变为更强大的解决方案,懒惰地抓取车辆元组并逐个或以块或其他方式处理它们。
# Remixed from: http://www.dabeaz.com/coroutines/cosax.py
# Don't shy away from reading http://www.dabeaz.com/coroutines/ if the stuff below
# seems weird.
from xml.sax import ContentHandler, parse
from collections import namedtuple
ElementStart = namedtuple('ElementStart', 'name attrs')
ElementEnd = namedtuple('ElementEnd', 'name')
class LazySax(ContentHandler):
def __init__(self, target):
self.target = target
def startElement(self, name, attrs):
self.target.send(ElementStart(name, attrs._attrs))
def endElement(self, name):
self.target.send(ElementEnd(name))
def pull_tuples(tuples):
while True:
event = yield
if isinstance(event, ElementStart) and event.name == 'vehicle':
vid = event.attrs['id']
edges = None
while True:
event = yield
if isinstance(event, ElementStart) and event.name == 'route':
edges = event.attrs['edges']
elif isinstance(event, ElementEnd) and event.name == 'vehicle':
tuples.append((vid, edges))
break
假设你有vehicles.xml
这个:
<root>
<foo />
<bar>
<!-- This block will be skipped. Try that with regex (please DON'T!).
<vehicle id="1292441" depart="26060.00">
<route edges="24449167#2 27659684#1 24686876#1"/>
</vehicle>
-->
<vehicle id="1292442" depart="26060.00">
<route edges="24449167#2 27659684#1 24686876#1"/>
</vehicle>
</bar>
<vehicle id="1292443" depart="26060.00">
<route edges="34449167#2 37659684#1 34686876#1"/>
</vehicle>
<vehicle id="1292444" depart="26060.00">
<route edges="44449167#2 47659684#1 44686876#1"/>
</vehicle>
</root>
现在,如果你这样做:
results = []
puller = pull_tuples(results); puller.next()
with open('vehicles.xml') as f:
parse(f, LazySax(puller))
for result in results:
print result
你会看到的:
(u'1292442', u'24449167#2 27659684#1 24686876#1')
(u'1292443', u'34449167#2 37659684#1 34686876#1')
(u'1292444', u'44449167#2 47659684#1 44686876#1')
这或多或少是你想要的。只是普通的旧 XML 解析。