2009-07-13 2 views
0

Я уже давно хотел улучшить свои навыки регулярного выражения, и «Освоение регулярных выражений» было рекомендовано несколько раз, поэтому я купил его и читал его за последний день или около того ,Улучшение моих навыков регулярного выражения

Я создал следующее регулярное выражение:

^(?:<b>)?(?:^<i>)?<a href="/site\.php\?id=([0-9]*)">(.*?) \(([ a-z0-9]{2,10})\)</a>(?:^</i>)?(?:</b>)?$ 

Какие матчи первые две ссылки, но игнорирует два обнесенный <i> тега. Он извлекает идентификатор, заголовок и тип.

<a href="/site.php?id=6321">site 1 title (type 1)</a> 
<b><a href="/site.php?id=10254">site 2 title (type 2)</a></b> 

<i><a href="/site.php?id=5479">site 3 title (type 3)</a></i> 
<b><i><a href="/site.php?id=325">site 4 title (type 4)</a></i></b> 

Несмотря на то, что это работает, кажется, довольно долго для чего-то такого простого, можно ли его улучшить?

+0

несколько вещей: Как это соответствует типу? Похоже, что это будет соответствовать словам, отличным от типа в parens. Кроме того, вы хотите, чтобы иметь возможность сопоставить что-то вроде «(нормальный материал здесь)» <---- обратите внимание, что нет закрывающего тега. Кроме того, вы хотите, чтобы id был пустым? т.е. - "id ="? – Tom

+0

Вы понимаете, что (?:)? не имеет «памяти» (?: ) ?. На самом деле вы, вероятно, хотите второй, только если появится первый. Формально говоря, регулярные выражения НЕ МОГУТ обработать это, хотя есть некоторые расширения регулярных выражений в определенных языках программирования, которые могут его обрабатывать (я думаю, они называют это обратным сопоставлением ... но это действительно не то, что могут делать регулярные выражения). – Tom

+0

На данный момент я просто хочу сопоставить приведенные выше примеры. Вы правы в конце тегов, и это пришло мне в голову, когда я его создавал. Кроме того, часть типа может содержать что угодно, а не только тип, за которым следует число. – DanCake

ответ

1

Если ваши пишущие экраны, как Whilliham справедливо упоминает DOM, может быть просто подходящим синтаксическим анализатором как Regex, поскольку HTML намного более прощает, чем регулярное выражение.

Не укоротить много, но немного регулярное выражение более терпим

  • Удалены начало строки и конец строки проверки, вы действительно нуждаетесь их?
  • отрицательные для просмотра назад убедитесь, что <a> не предваряются <i>
  • использования \ г простого asertation вместо [0-9] тада уборщика.
  • У вас был тип длиной от 3 до 11 символов, я изменил его на 3 или более.
  • удаленные проверки для концевых тегов, они не служат контекстуальному значению для вашего скриншота (предположительно).

(?<!<i>)<a href="/site.php\?id=(\d*)">(.*?) \(([ a-z\d]{2,})\)

+0

Спасибо! Это было действительно полезно. Я посмотрю на взгляды и взгляды, поскольку они кажутся удобными. – DanCake

5

Недостаточно использовать классы символов (\ d для 0-9 и т. Д.). Я не вижу, чтобы рассматриваемое регулярное выражение могло быть значительно сокращено; однако ...

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

+0

Не просто опасно ... просто неправильно ... регулярные выражения не предназначены для работы с html, потому что они нечувствительны к контексту. +1 для указания, что это плохо. – Tom

+0

так много из этих вопросов. как сообщить им об этом? сделать faq? lol – Victor

+0

@Victor: Хотел бы я знать.Я думаю, что часть проблемы заключается в том, что термин «регулярное выражение» злоупотребляется. Существует так много вариантов и расширений, добавленных языками, которые делают regexes более мощными ... Я думаю, это заставляет людей думать, что они являются решением всех проблем синтаксического анализа. Иногда вы можете делать быстрые и грязные вещи с ними для html (если вы делаете определенные предположения о своих данных) ... но все же, я бы хотел, чтобы был простой способ для людей наткнуться на то, что они не должны их использовать для анализа контекстно-зависимых грамматик. – Tom

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