Regex: сопоставить HTML-тег, только если он содержит определенный идентификатор класса - PullRequest
0 голосов
/ 30 июля 2010

Совпадение тега html с использованием регулярного выражения perl в php.

Хотите, чтобы тег совпадал, если он содержит "class = details" где-то в открытом теге.

Желание совпадения <table border="0" class="details"> не <table border="0">

Написал, чтобы соответствовать:

'#<table(.+?)class="details"(.+?)>#is'

<table(.+?) создает проблему, так как он соответствует первому найденному тегу таблицы, только останавливая совпадение, когда находит class="details", независимо от того, как далеко внизу происходит код.

Я думаю, эта логика решит мою проблему:

"Совпадение <table, но только если оно содержит class="details" до следующего >"

Как я могу написать это?

Ответы [ 4 ]

3 голосов
/ 30 июля 2010

Хотя регулярные выражения могут быть полезны для самых разных задач, я считаю, что при анализе 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');
1 голос
/ 30 июля 2010

HTML не разбирается (надежно) с помощью регулярных выражений. Есть несколько простых случаев, которые имеют решение, но они являются исключениями. Я думаю, что ваше дело неразрешимо с помощью регулярных выражений, но я не уверен

Вы должны работать с ним, используя инструменты XML и парсеры XML, такие как XPath, для поиска и тестирования ваших условий. Здесь очень просто написать выражение, соответствующее вашему случаю. Я не знаю, как построить дерево XML и выполнить запрос XPath в PHP, но выражение XPath равно

//table[@class='details']
1 голос
/ 30 июля 2010

Вам, вероятно, понадобится позитивный взгляд в какой-то форме, как очень грубый, который явно имеет свои ограничения ...

<table(?=[^>]*class="details")[^>]*>
0 голосов
/ 01 июля 2014

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

<\/?table[^>]*(class="details")*>

Но вышеуказанные пользователи правы, говоря, что было бы гораздо лучше использовать синтаксический анализатор типов xml / html для поиска вашего элемента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...