Соответствует тегу html с использованием perl regex в php.
Хотите, чтобы тег соответствовал, если он содержит «class = details» где-то в открытом теге.
Желание сопоставления <table border="0" class="details">
not <table border="0">
Написал это, чтобы он соответствовал:
'#<table(.+?)class="details"(.+?)>#is'
<table(.+?)
Создает проблему, так как она соответствует первому тегу таблицы, который находит только прекращение совпадения, когда он находит class="details"
независимо от того, насколько далеко он находится в коде.
Я думаю, что эта логика исправит мою проблему:
«Матч <table
но только если он содержит class="details"
перед следующим >
"
Как я могу это написать?
Хотя регулярные выражения могут быть полезны для большого числа задач, я считаю, что это обычно не подходит при анализе HTML DOM. Проблема с HTML заключается в том, что структура вашего документа настолько изменчива, что трудно точно (и точно я имею в виду 100% -ный шанс успеха без ложных срабатываний) извлекают тег.
Я рекомендую вам использовать парсер DOM, такой как phpQuery
и использовать его как таковой:
function get_first_image($html){ $dom = phpQuery::newDocument($html); $first_img = $dom->find('img:first'); if($first_img !== null) { return $first_img->attr('src'); } return null; }
Некоторые могут подумать, что это слишком много, но, в конце концов, его будет легче поддерживать, а также расширять. Например, используя парсер DOM, я также могу получить атрибут alt.
Регулярное выражение можно было бы разработать для достижения одной и той же цели, но было бы ограничено таким образом, что это заставит атрибут alt
быть после src
или наоборот, и преодоление этого ограничения добавит сложности к регулярному выражению.
Также рассмотрим следующее. Чтобы правильно сопоставить <img>
с помощью регулярных выражений и получить только атрибут src
(захвачен в группе 2), вам понадобится следующее регулярное выражение:
<\s*?img\s+[^>]*?\s*src\s*=\s*(["'])((\\?+.)*?)\1[^>]*?>
И снова, вышеизложенное может потерпеть неудачу, если:
i
не используется. src
. src
использует символ >
где-то в своем значении. Поэтому снова просто не используйте регулярные выражения для анализа документа dom.
Простой пример того, как решить вашу проблему с помощью phpQuery
:
$dom = phpQuery::newDocument($html); $matching_tags = $dom->find('.details');
Вам, вероятно, понадобится Положительный Взгляд в какой-то форме, как очень грубый, который явно имеет свои ограничения …
<table(?=[^>]*class="details")[^>]*>
HTML не поддается анализу (надежно) с использованием регулярных выражений. Есть несколько простых случаев, которые имеют решение, но они являются исключениями. Я думаю, что ваше дело неразрешимо с помощью регулярного выражения, но я не уверен
Вы должны работать с ним с помощью инструментов XML и парсеров XML, таких как XPath, для поиска и тестирования ваших условий. Очень просто написать выражение, соответствующее вашему делу. Я не знаю, как построить дерево XML и выполнить запрос XPath в PHP, но выражение XPath
//table[@class='details']
Вы могли бы использовать Regex, как показано ниже:
<\/?table[^>]*(class="details")*>
Но вышеупомянутые пользователи верны, говоря, что было бы гораздо лучше использовать синтаксический анализатор xml / html, чтобы найти ваш элемент.