Регулярное выражение для извлечения атрибутов тега - PullRequest
46 голосов
/ 25 ноября 2008

Я пытаюсь извлечь атрибуты тега привязки (<a>). Пока у меня есть это выражение:

(?<name>\b\w+\b)\s*=\s*("(?<value>[^"]*)"|'(?<value>[^']*)'|(?<value>[^"'<> \s]+)\s*)+

, который работает для таких строк, как

<a href="test.html" class="xyz">

и (одинарные кавычки)

<a href='test.html' class="xyz">

но не для строки без кавычек:

<a href=test.html class=xyz>

Как я могу изменить свое регулярное выражение, чтобы оно работало с атрибутами без кавычек? Или есть лучший способ сделать это?

Спасибо!

Обновление: Спасибо за все хорошие комментарии и советы. Есть одна вещь, которую я не упомянул: мне, к сожалению, приходится исправлять / изменять код, написанный не мной сам. И нет времени / денег, чтобы переписать этот материал снизу вверх.

Ответы [ 18 ]

2 голосов
/ 25 ноября 2008

Я предлагаю использовать HTML Tidy для преобразования HTML в XHTML, а затем использовать подходящее выражение XPath для извлечения атрибутов.

2 голосов
/ 25 ноября 2008

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

Тогда вы можете использовать XPath.

1 голос
/ 25 ноября 2008

Я бы пересмотрел стратегию, чтобы использовать только одно регулярное выражение. Конечно, это хорошая игра, чтобы придумать единственное регулярное выражение, которое делает все это. Но с точки зрения поддержания способности вы собираетесь выстрелить себе в обе ноги.

0 голосов
/ 30 ноября 2016

Это работает для меня. Также учитываются некоторые конечные случаи, с которыми я столкнулся.

Я использую это регулярное выражение для парсера XML

(?<=\s)[^><:\s]*=*(?=[>,\s])
0 голосов
/ 26 июня 2015

посмотрите на это Regex & PHP - изолировать атрибут src от тега img

возможно, вы сможете пройти через DOM и получить нужные атрибуты. У меня работает нормально, получаю атрибуты из тега body

0 голосов
/ 01 февраля 2015

Я создал PHP-функцию , которая может извлекать атрибуты любых тегов HTML. Он также может обрабатывать такие атрибуты, как disabled, которые не имеют значения, а также может определять, является ли тег автономным тегом (не имеет закрывающего тега) или нет (имеет закрывающий тег), проверяя результат content:

/*! Based on <https://github.com/mecha-cms/cms/blob/master/system/kernel/converter.php> */
function extract_html_attributes($input) {
    if( ! preg_match('#^(<)([a-z0-9\-._:]+)((\s)+(.*?))?((>)([\s\S]*?)((<)\/\2(>))|(\s)*\/?(>))$#im', $input, $matches)) return false;
    $matches[5] = preg_replace('#(^|(\s)+)([a-z0-9\-]+)(=)(")(")#i', '$1$2$3$4$5<attr:value>$6', $matches[5]);
    $results = array(
        'element' => $matches[2],
        'attributes' => null,
        'content' => isset($matches[8]) && $matches[9] == '</' . $matches[2] . '>' ? $matches[8] : null
    );
    if(preg_match_all('#([a-z0-9\-]+)((=)(")(.*?)("))?(?:(\s)|$)#i', $matches[5], $attrs)) {
        $results['attributes'] = array();
        foreach($attrs[1] as $i => $attr) {
            $results['attributes'][$attr] = isset($attrs[5][$i]) && ! empty($attrs[5][$i]) ? ($attrs[5][$i] != '<attr:value>' ? $attrs[5][$i] : "") : $attr;
        }
    }
    return $results;
}

Тестовый код

$test = array(
    '<div class="foo" id="bar" data-test="1000">',
    '<div>',
    '<div class="foo" id="bar" data-test="1000">test content</div>',
    '<div>test content</div>',
    '<div>test content</span>',
    '<div>test content',
    '<div></div>',
    '<div class="foo" id="bar" data-test="1000"/>',
    '<div class="foo" id="bar" data-test="1000" />',
    '< div  class="foo"     id="bar"   data-test="1000"       />',
    '<div class id data-test>',
    '<id="foo" data-test="1000">',
    '<id data-test>',
    '<select name="foo" id="bar" empty-value-test="" selected disabled><option value="1">Option 1</option></select>'
);

foreach($test as $t) {
    var_dump($t, extract_html_attributes($t));
    echo '<hr>';
}
0 голосов
/ 27 ноября 2012

Мне тоже это нужно и я написал функцию для разбора атрибутов, вы можете получить ее здесь:

https://gist.github.com/4153580

(Примечание: не используется регулярное выражение)

0 голосов
/ 18 сентября 2012

Извлеките элемент:

var buttonMatcherRegExp=/<a[\s\S]*?>[\s\S]*?<\/a>/;
htmlStr=string.match( buttonMatcherRegExp )[0]

Затем используйте jQuery для анализа и извлечения нужного бита:

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