2014-01-03 1 views
-2

У меня есть строка, как это:как получить submatch матча в питона регулярных выражений

Str =»< ТЕМЫ> < D> какао </D> </ТЕМЫ> < МЕСТ

> < D > эль-Сальвадор </D> < D> США </D> < D> уругвай </D> </МЕСТ>»

Я хочу, чтобы получить строку между < D> и </D> в < ДОСТОПРИМЕЧАТЕЛЬНОСТИ> и </ДОСТОПРИМЕЧАТЕЛЬНОСТИ>. Я знал проточный:

p1=re.compile(r'(?<=<PLACES>)(.*?)(?=</PLACES>)') 
p2=re.compile(r'(?<=<D>)(.*?)(?=</D>)') 

с p1 и p2, я могу получить эль-Салвадор, США, uruguay.But как я могу получить информацию с только р.

+0

Избегайте использования регулярное выражение и использовать парсер. – hwnd

+1

[обязательное чтение] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) – shx2

ответ

1

Вы можете использовать регулярные выражения, как этот:

(?<=<D>)([^<>]*)(?=</D>)(?=(?:(?!<PLACES>).)*</PLACES>) 

regex101 demo

Где положительный предпросмотр (?=(?:(?!<PLACES>).)*</PLACES>) убеждается есть </PLACES> где-то впереди, без открытия <PLACES> в между тем, что согласуется и закрытие тег.

Но вы действительно должны рассмотреть вопрос об использовании надлежащего парсер, такие как BeautifulSoup:

>>> from bs4 import BeautifulSoup 
>>> text = '<TOPICS><D>cocoa</D></TOPICS><PLACES><D>el-salvador</D><D>usa</D><D>uruguay</D></PLACES>' 
>>> soup = BeautifulSoup(text) 
>>> for m in soup.find_all('d'): 
...  if m.parent.name == 'places': 
...   print(''.join(m)) 
... 
el-salvador 
usa 
uruguay 

EDIT: Как было предложено JonClements в комментариях, вы также можете использовать:

>>> for m in soup.select('places d'): 
...  print(''.join(m)) 
... 
el-salvador 
usa 
uruguay 
+1

В качестве альтернативы используйте select ... 'for m in soup.select ('places d') ' –

+0

@JonClements Awesome! – Jerry

+0

Я не хочу разбирать весь xml, но только текст в некоторой указанной метке. Я думаю, что Regex работает быстрее. Спасибо за ваш совет. :) – Lambda

Смежные вопросы