RegEx для извлечения всех атрибутов HTML-тегов, включая встроенный JavaScript - PullRequest
3 голосов
/ 08 марта 2010

Я нашел этот полезный код регулярного выражения, когда собирался проанализировать атрибуты HTML-тега:

(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?

Отлично работает, но в нем отсутствует один ключевой элемент, который мне нужен. Некоторые атрибуты являются триггерами событий, в которых есть встроенный код Javascript, например:

onclick="doSomething(this, 'foo', 'bar');return false;"

Или:

onclick='doSomething(this, "foo", "bar");return false;'

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

Я ДОЛЖЕН добавить, что это не используется для разбора всего HTML-документа. Он используется в качестве аргумента в старой функции «выбор массива», которую я обновил. Одним из аргументов является тег, который может добавлять дополнительные атрибуты HTML к элементу формы.

Я сделал улучшенную функцию и осуждаю старую ... но в случае, если где-то в коде есть вызов старой функции, мне нужно, чтобы она была проанализирована в новом формате массива. Пример:

// Old Function
function create_form_element($array, $type, $selected="", $append_att="") { ... }
// Old Call
create_form_element($array, SELECT, $selected_value, "onchange=\"something(this, '444');\"");

Новая версия использует массив пар attr => value для создания дополнительных тегов.

create_select($array, $selected_value, array('style' => 'width:250px;', 'onchange' => "doSomething('foo', 'bar')"));

Это просто проблема обратной совместимости, когда все вызовы OLD-функции направляются в новую, но аргумент $ append_att в старой функции необходимо преобразовать в массив для новой, поэтому мне нужно использовать регулярное выражение для анализа небольших фрагментов HTML. Если есть лучший и легкий способ сделать это, я открыт для предложений.

Ответы [ 3 ]

2 голосов
/ 20 марта 2010

Проблема с вашим регулярным выражением заключается в том, что оно пытается обрабатывать как одинарные, так и двойные кавычки одновременно. Он не поддерживает значения атрибутов, которые содержат другую кавычку. Это регулярное выражение будет работать лучше:

(\w+)=("[^<>"]*"|'[^<>']*'|\w+)
1 голос
/ 06 июля 2013

следующее регулярное выражение будет работать в соответствии со спецификациями синтаксиса HTML, доступными здесь

http://www.w3.org/TR/html-markup/syntax.html

регулярных выражений

// valid tag names
$tagname = '[0-9a-zA-Z]+';
// valid attribute names
$attr = "[^\s\\x00\"'>/=\pC]+";
// valid unquoted attribute values
$uqval = "[^\s\"'=><`]*";
// valid single-quoted attribute values
$sqval = "[^'\\x00\pC]*";
// valid double-quoted attribute values
$dqval = "[^\"\\x00\pC]*";
// valid attribute-value pairs
$attrval = "(?:\s+$attr\s*=\s*\"$dqval\")|(?:\s+$attr\s*=\s*'$sqval')|(?:\s+$attr\s*=\s*$uqval)|(?:\s+$attr)"; 

и окончательный запрос регулярного выражения будет

    // start tags + all attr formats
    $patt[] = "<(?'starttags'$tagname)(?'tagattrs'($attrval)*)\s*(?'voidtags'[/]?)>";

    // end tags
    $patt[] = "</(?'endtags'$tagname)\s*>"; // end tag

    // full regex pcre pattern
    $patt = implode("|", $patt);
    // search and match
    preg_match_all("#$patt#imuUs",$data,$matches);

надеюсь, это поможет.

0 голосов
/ 12 октября 2011

Еще лучше было бы использовать обратные ссылки, в PHP регулярное выражение было бы:

([a-zA-Z_:][-a-zA-Z0-9_:.]+)=(["'])(.*?)\\2

Где \\2 является ссылкой на (["'])

Также это регулярное выражение будет соответствовать атрибутам, содержащим _, - и :, которые разрешены в соответствии с W3C, однако это выражение не будет соответствовать атрибутам, значения которых не содержатся в кавычках.

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