2013-11-16 3 views
1

Я пытаюсь получить все теги, содержащие поле «имя», а затем обрабатывать все предложение плюс имя. Это тестовый код у меня есть:Python re.findall

sourceCode = '<dirtfields name="one" value="stuff">\n<gibberish name="two"\nwewt>' 
namesGroup = re.findall('<.*name="(.*?)".*>', sourceCode, re.IGNORECASE | re.DOTALL) 

for name in namesGroup: 
    print name 

Какой выход:

two 

И выход я пытаюсь искать будет

['<dirtfields name="one" value="stuff">', 'one'] 
['<gibberish name="two"\nwewt>', 'two'] 

EDIT: Найденный способ сделать это, благодаря doublesharp для более чистого способа получить значение «имя».

namesGroup = re.findall(r'(<.*?name="([^"]*)".*?>)', sourceCode, re.IGNORECASE | re.DOTALL) 

Что будет:

('<dirtfields name="one" value="stuff">', 'one') 
('<gibberish name="two"\nwewt>', 'two') 

ответ

3

Ваше регулярное выражение откусил - вы соответствия слишком много (вплоть до последнего >). Так как вы только должны значения между двойными кавычками после name= использовать следующую схему:

name="([^"]*)" 
  • name=" совпадает с первой частью атрибута, которого вы ищете
  • ([^"]*) создает сгруппированный матч, основываясь на каких-либо символах то есть не a double quote
  • " соответствует двойной кавычке после значения атрибута name.

И ваш код будет выглядеть следующим образом (это хорошая форма включить r до вашего шаблона):

namesGroup = re.findall(r'name="([^"]*)"', sourceCode, re.IGNORECASE) 
+0

Большое спасибо doublesharp. Это более чистый способ получить это =) – Neomind

+0

're.DOTALL' здесь бесполезен. –

+0

@ CasimiretHippolyte Очень верно ... ах вырезать и вставлять. Убрали его для ясности. – doublesharp

3

Очевидно, вы имеете дело с HTML или XML файлом и ищете для некоторых значений конкретного атрибута ,

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

Как BeautifulSoup4, тот больше всего мне нравится, вот очень краткий пример того, как использовать его:

from bs4 import BeautifulSoup 

sourceCode = '<dirtfields name="one" value="stuff">\n<gibberish name="two"\nwewt>' 

soup = BeautifulSoup(sourceCode) 
print soup.prettify() 
print '------------------------' 
for tag in soup.find_all(): 
    if tag.has_key('name'): 
     print tag, tag['name'] 

Выходной сигнал выглядит немного уродливое сейчас (выход даже неправильно), но это показывает, что как beautifulsoup автоматически исправит ваш сломанный html и легко найдет необходимый вам атрибут.

<html> 
<body> 
    <dirtfields name="one" value="stuff"> 
    <gibberish name="two" wewt=""> 
    </gibberish> 
    </dirtfields> 
</body> 
</html> 
------------------------ 
<dirtfields name="one" value="stuff"> 
<gibberish name="two" wewt=""></gibberish></dirtfields> one 
<gibberish name="two" wewt=""></gibberish> two 

Добавить Beautifulsoup в ваших любимых тегов StackOverflow, и вы будете удивление, как это хорошо и как много людей делают то же самое, как вы с более мощным инструментом!

+0

Кроме того, вы [не можете анализировать HTML с регулярными выражениями] (http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html), потому что [HTML не является обычным языком ] (http://howiprovedit.com/archives/44)! Существует даже целый [SO Question on this] (http://stackoverflow.com/questions/590747/using-regular-expressions-to-parse-html-why-not). – Livius

2
(?<=name=")[^"]* 

Если вы хотите, чтобы соответствовать только имя без захвата группы, вы можете использовать:

re.findall(r'(?<=name=")[^"]*', sourceCode, re.IGNORECASE) 

Выход:['one', 'two']

Конечно захвата группы одинаково приемлемое решение ,

0

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

myreg = re.compile(r""" 
    < (?: [^n>]+ | \Bn | n(?!ame\s*=))+ # begining of the tag 
              # until the name attribute 
    name \s* = \s* ["']?     # attribute until the value 
    ((?: [^\s\\"']+ | \\{2} | \\.)*) # value 
    [^>]*>         # end of the tag 
""", re.X | re.I | re.S) 

namesGroup = myreg.findall(sourceCode) 

Однако использование BS4 является хорошим решением для Вашего случая.

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