2013-03-13 3 views
0

Я пытаюсь разобрать следующие две строки в Python:Разбор строки в Python

Вот первая строка

s1="<one> <two> <three> here's one attribute < six : 10.3 > < seven : 8.5 > < eight : 90.1 > < nine : 8.7 >" 

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

0 one  
1 two 
2 three 
3 here's one attribute 
4 six : 10.3 
5 seven : 8.5 
6 eight : 90.1 
7 nine : 8.7 

Вот вторая строка

s2="<one><two><three> an.attribute ::" 

Итак, подобным образом, мне нужны элементы, хранящиеся в списке, как это:

0 one 
1 two 
2 three 
3 an.attribute 

Вот что я пытался до сих пор, повторное это ответ, который я получил от другого вопроса я отправил на Переполнение стека.

res = re.findall('< (.*?) >', s1) 
pprint(res) 
index=0 
for index in res: 
    print index 

но проскакивают "вот один атрибут"

выход:

['one', 'two', 'three', 'six : 10.3', 'seven : 8.5', 'eight : 90.1', 'nine : 8.7'] 
one 
two 
three 
six : 10.3 
seven : 8.5 
eight : 90.1 
nine : 8.7 

Может кто-нибудь помочь мне? =)

Если кто-нибудь знает, как извлечь числовые значения из строки, как 10,3, 8,5, 90,1 и 8,7 из первой строки тоже, что было бы слишком большой =)

EDIT: Дункан Я попытался ваш код, но я, похоже, не получаю вывод, как должен. Я предполагаю, что где-то я сделал какую-то ошибку. не могли бы вы сказать мне, что это такое?

from __future__ import generators 
from pprint import pprint 
s2="<one><two><three> an.attribute ::" 
s1="<one> <two> <three> here's one attribute < six : 10.3 > < seven : 8.5 > < eight : 90.1 > < nine : 8.7 >" 
def parse(s): 
    for t in s.split('<'): 
     for u in t.strip().split('>',1): 
      if u.strip(): yield u.strip() 

list(parse(s1)) 
list(parse(s2)) 
pprint(s1) 
pprint(s2) 

Вот результат я получаю:

"<one> <two> <three> here's one attribute < six : 10.3 > < seven : 8.5 > < eight : 90.1 > < nine : 8.7 >" 
'<one><two><three> an.attribute ::' 
+0

http://docs.python.org/2/library/re.html – vartec

+0

@daveoncode Я обновил мой вопрос, не могли бы вы еще раз взглянуть? :) – Anon

+0

@vartec Спасибо за ссылку, я посмотрел на это, но еще не понял, но – Anon

ответ

1

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

def parse(s): 
    for t in s.split('<'): 
     for u in t.strip().split('>',1): 
      if u.strip(): yield u.strip() 

>>> list(parse(s1)) 
['one', 'two', 'three', "here's one attribute", 'six : 10.3', 'seven : 8.5', 'eight : 90.1', 'nine : 8.7'] 
>>> list(parse("<one><two><three> an.attribute ::")) 
['one', 'two', 'three', 'an.attribute ::'] 

>>> from pprint import pprint 
>>> pprint(list(parse(s1))) 
['one', 
'two', 
'three', 
"here's one attribute", 
'six : 10.3', 
'seven : 8.5', 
'eight : 90.1', 
'nine : 8.7'] 

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

>>> [ u.strip() for t in s1.split('<') for u in t.strip().split('>',1) if u.strip() ] 
['one', 'two', 'three', "here's one attribute", 'six : 10.3', 'seven : 8.5', 'eight : 90.1', 'nine : 8.7'] 
+0

не могли бы вы взглянуть на редактирование, которое я добавил в свой вопрос :) – Anon

+0

Конечно. Вы вызываете 'list (parse (s1)', а затем просто печатаете 's1'. Попробуйте' pprint (list (parse (s1))) ', чтобы увидеть обработанный вывод. – Duncan

+0

спасибо, вот что мне нужно =) – Anon

2

Это становится все вещи, я уверен, что вы можете добавить некоторые, если заявления и хитрости, чтобы получить точные результаты желаемого

c = 0 
m=re.compile('< (\w+) (: ([\d.]+))* *> ([^<]*)') 
for r in m.finditer(s1): 
    c = c + 1 
    (tag,junk,number,attribute)=r.groups() 
    print c, attribute 

EDIT: более объяснений

re.compile линия готовит регулярное выражение для использования Б.Р. сделайте так, что это regexp делает, сначала вы должны понять, что круглые скобки() обозначают элементы, которые будут попадать в результаты (r.groups())

Таким образом, выражение < (\ w +) означает поиск <, затем пробел, затем начать захват группы группа захвата содержит один или несколько «символов слова», такие вещи, как а к г

Это, как тег найден

Следующая бит (([\ d.] +)) * Снова начинается группа захвата, тогда a: должно присутствовать, а затем другая группа захвата, им разрешено находиться внутри друг друга. Квадратные скобки [] определяют класс символов, а \ d - соответствие цифр. . в этом контексте это просто точка!Таким образом, класс будет соответствовать любому значению или цифре . Значение «+» означает «1 или более предыдущего выражения», поэтому это одна или несколько цифр или точек. Это чтобы получить номер. Наконец, после того, как круглые скобки закрывают группы захвата, есть астерикс * Это означает, что он фиксирует ноль или более предыдущего выражения. Это приводит к тому, что предыдущая группа является необязательной. Не все теги имеют номера.

Я остановил свое объяснение регулярного выражения. Есть много больших ресурсов для обучения, как построить РегВыр

finditer просто повторяет регулярное выражение на строках и находит спичку из него

Выражения (tag,junk,number,attribute)=r.groups() означает копирование результата списка (r.group) индивид переменные тега, мусор, количество атрибутов и

+0

Это не помогло мне = ( – Anon

+0

не могли бы вы объяснить, что делает ваш код – Anon

+0

Большое спасибо за подробное объяснение =) – Anon