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

次のストリーム指向の XML 解析ハックでは、Python 標準ライブラリのみを使用します。

長々とした回答で申し訳ありません:XMLの解析は非常に面倒なので、「創造的に」行う方法を見つけることを好みます:)

次のコードは、結果のタプルをリストに蓄積します。しかし、コルーチンは任意の方法で連鎖できるため、車両のタプルを遅延取得して 1 つずつまたはチャンクなどで処理する、より堅牢なソリューションにこれを進化させることができます。

# 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 に答える
0

lxmlなどの XML パーサーを使用します。これにより、必要な要素とその属性に簡単にアクセスできます。1 つの属性のさまざまなルート エッジに関しては、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 に答える