Web

Получение атрибута href элемента A

Я пытаюсь найти ссылки на странице. Вот мое регулярное выражение:

/<a\s[^>]*href=(\"\'??)([^\"\' >]*?)[^>]*>(.*)<\/a>/

 

но, похоже, оно не работает:

<a title="this" href="that">what?</a>

 

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

 

Ответ 1

Создать надежное регулярное выражение для HTML сложная задача. Вот как это можно сделать с помощью DOM:

$dom = new DOMDocument;

$dom->loadHTML($html);

foreach ($dom->getElementsByTagName('a') as $node) {

    echo $dom->saveHtml($node), PHP_EOL;

}

 

Вышеупомянутый код найдет и выведет "externalHTML" для всех тегов « в $html строке.

Чтобы получить все текстовые значения узла, выполните:

echo $node->nodeValue; 

 

Чтобы проверить, существует ли href  атрибут, можно сделать:

echo $node->hasAttribute( 'href' );

 

Для того, чтобы получить href  атрибут:

echo $node->getAttribute( 'href' );

 

Для того, чтобы изменить href атрибут:

$node->setAttribute('href', 'something else');

 

Для того, чтобы удалить href атрибут:

$node->removeAttribute('href');

 

Вы также можете запросить href атрибут напрямую с помощью XPath:

$dom   = new DOMDocument;

$dom->loadHTML($html);

$xpath = new DOMXPath($dom);

$nodes = $xpath->query('//a/@href');

foreach($nodes as $href) {

    echo $href->nodeValue;                                 // echo значения текущего атрибута

    $href->nodeValue = 'new value';                    // установка нового значения

    $href->parentNode->removeAttribute('href'); // удаление атрибута

}

 

Ответ 2

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

/^<a.*?href=(["\'])(.*?)\1.*$/

 

Это соответствует <a в начале строки, за которым следует любое количество символов .*?, затем href=, за которым следует ссылка, окруженная " или ':

$str = '<a title="this" href="that">what?</a>';

preg_match('/^<a.*?href=(["\'])(.*?)\1.*$/', $str, $m);

var_dump($m);

Вывод:

array(3) {

  [0] => string(37) "<a title="this" href="that">what?</a>"

  [1] => string(1) """

  [2] => string(4) "that"

}

 

Ответ 3

Почему бы вам просто не сопоставить:

"<a.*?href\s*=\s*['"](.*?)['"]"

 

<?php

$str = '<a title="this" href="that">what?</a>';

$res = array();

preg_match_all("/<a.*?href\s*=\s*['\"](.*?)['\"]/", $str, $res);

var_dump($res);

?>

 

Тогда:

$ php test.php

array(2) {

  [0]   => array(1) {

    [0] => string(27) "<a title="this" href="that""

  }

  [1]   => array(1) {

    [0] => string(4) "that"

  }

}

 

Ответ 4

Далее работает для меня и возвращается как href и value из тега <a>.

preg_match_all("'\<a.*?href=\"(.*?)\".*?\>(.*?)\<\/a\>'si", $html, $match);

if($match) {

    foreach($match[0] as $k => $e) {

        $urls[] = array(

            'anchor'   =>  $e,

            'href'        =>  $match[1][$k],

            'value'     =>  $match[2][$k]

        );

    }

}

 

Многомерный массив под названием $urls теперь содержит ассоциативные подмассивы, которые легко использовать. 

Схожие статьи

Django: уязвимости, от которых нужно защитить сайт в первую очередь
Web

Django: уязвимости, от которых нужно защитить сайт в первую очередь

Web

Получение разрешения экрана с помощью PHP

Web

Как использовать символы Юникода в PHP строках

Web

Использование цикла для SimpleXML с помощью foreach в php

×