Python RE:我如何忽略标签之间的空白空间?

时间:2012-10-24 17:33:40

标签: python xml-parsing

我有以下文字:

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

不会这样做。

3 个答案:

答案 0 :(得分:0)

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

那就是说,为什么不仅仅strip()之后的多余空格呢?

答案 1 :(得分: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']

答案 2 :(得分: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解析。