2013-06-28 2 views
1

Я хочу использовать модуль re, чтобы извлечь все узлы html из строки, включая все их attrs. Тем не менее, я хочу, чтобы каждый attr был группой, а это значит, что я могу использовать matchobj.group(), чтобы получить их. Число attrs в узле гибко. Здесь я смущен. Я не знаю, как написать такое регулярное выражение. Я пробовал </?(\w+)(\s\w+[^>]*?)*/?>', но для узла вроде <a href='aaa' style='bbb'> Я могу получить только две группы с [('a'), ('style="bbb")].
Я знаю, что есть некоторые хорошие парсеры HTML. Но на самом деле я не собираюсь извлекать значения attrs. Мне нужно изменить исходную строку.Использование regex для извлечения всех html attrs

+1

FFS ... http://www.crummy.com/software/BeautifulSoup/ –

+0

Рассмотрите возможность использования HTML парсеры вместо Regex , http://www.crummy.com/software/BeautifulSoup/ – Achrome

+0

Нормальный первый матч перезаписывается вторым. –

ответ

1

Описание

Чтобы захватить бесконечное число атрибутов, то необходимо будет двухстадийный процесс, в котором сначала тянуть весь элемент. Затем вы будете проходить через элементы и получать массив согласованных атрибутов.

регулярное выражение, чтобы захватить все элементы: <\w+(?=\s|>)(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?>

enter image description here

регулярное выражение, чтобы захватить все атрибуты из одного элемента: \s\w+=(?:'[^']*'|"[^"]*"|[^'"][^\s>]*)(?=\s|>)

enter image description here

Python Пример

См работы пример: http://repl.it/J0t/4

Код

import re 

string = """ 
<a href="i.like.kittens.com" NotRealAttribute=' true="4>2"' class=Fonzie>text</a> 
"""; 

for matchElementObj in re.finditer(r'<\w+(?=\s|>)(?:[^>=]|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s>]*)*?>', string, re.M|re.I|re.S): 
    print "-------" 
    print "matchElementObj.group(0) : ", matchElementObj.group(0) 

    for matchAttributesObj in re.finditer(r'\s\w+=(?:\'[^\']*\'|"[^"]*"|[^\'"][^\s>]*)(?=\s|>)', string, re.M|re.I|re.S): 
     print "matchAttributesObj.group(0) : ", matchAttributesObj.group(0) 

Выход

------- 
matchElementObj.group(0) : <a href="i.like.kittens.com" NotRealAttribute=' true="4>2"' class=Fonzie> 
matchAttributesObj.group(0) : href="i.like.kittens.com" 
matchAttributesObj.group(0) : NotRealAttribute=' true="4>2"' 
matchAttributesObj.group(0) : class=Fonzie 
3

Please don't use regex. Используйте BeautifulSoup:

>>> from bs4 import BeautifulSoup as BS 
>>> html = """<a href='aaa' style='bbb'>""" 
>>> soup = BS(html) 
>>> mytag = soup.find('a') 
>>> print mytag['href'] 
aaa 
>>> print mytag['style'] 
bbb 

Или, если вы хотите, словарь:

>>> print mytag.attrs 
{'style': 'bbb', 'href': 'aaa'} 
+0

Я знаю, что парсеры HTML должны быть хорошим выбором, но на самом деле я не думаю, что они могут работать на меня. Мне нужно изменить исходную строку. – zhangyangyu

+0

@zhangyangyu Взгляните на [это] (http://www.crummy.com/software/BeautifulSoup/bs4/doc/#replace-with), возможно, – TerryA

+0

Может ли downvoter прояснить, почему они были downvoted – TerryA