0

我有以下文字:

<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+ 

不这样做。

4

3 回答 3

0

那是 XML。您应该使用 XML 解析器,而不是正则表达式。

也就是说,为什么不只是strip()之后多余的空白呢?

于 2012-10-24T17:35:56.873 回答
0

使用像lxml这样的 XML 解析器。这将使您可以轻松访问所需的元素及其属性。对于一个属性中不同的路由边,使用split()字符串的方法:

In [1]: edges="24449167#2 27659684#1 24686876#1"

In [2]: edges.split()
Out[2]: ['24449167#2', '27659684#1', '24686876#1']
于 2012-10-24T20:30:58.017 回答
0

以下面向流的 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 解析。

于 2012-10-25T18:25:32.823 回答