Схват атрибута href элемента A

Попытка найти ссылки на странице.

мое регулярное выражение:

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

но, похоже,

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

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

Надежное Regex для HTML сложно . Вот как это сделать с DOM :

 $dom = new DOMDocument; $dom->loadHTML($html); foreach ($dom->getElementsByTagName('a') as $node) { echo $dom->saveHtml($node), PHP_EOL; } 

Вышеизложенное обнаружит и выведет «внешнийHTML» всех элементов A в строке $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 current attribute value $href->nodeValue = 'new value'; // set new attribute value $href->parentNode->removeAttribute('href'); // remove attribute } 

Также см:

  • Лучшие методы анализа HTML
  • DOMDocument в php

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

Я согласен с Gordon, вы должны использовать парсер HTML для анализа 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" } 

Образцом, который вы хотите найти, будет шаблон привязки ссылок, например (что-то):

 $regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/"; 

почему бы вам просто не согласиться

 "<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" } } 

который работает. Я только что удалил первые привязки захвата.

Я не уверен, что вы пытаетесь сделать здесь, но если вы пытаетесь проверить ссылку, посмотрите на PHP filter_var ()

Если вам действительно нужно использовать регулярное выражение, то ознакомьтесь с этим инструментом, это может помочь: http://regex.larsolavtorvik.com/

Используя ваше регулярное выражение, я немного изменил его в соответствии с вашими потребностями.

<a.*?href=("|')(.*?)("|').*?>(.*)<\/a>

Я лично предлагаю вам использовать HTML Parser

EDIT: Протестировано

Для тех, кто еще не получает решения очень легко и быстро, используя SimpleXML

 $a = new SimpleXMLElement('<a href="www.something.com">Click here</a>'); echo $a['href']; // will echo www.something.com 

Его работа для меня

Быстрый тест: <a\s+[^>]*href=(\"\'??)([^\1]+)(?:\1)>(.*)<\/a> похоже, делает трюк, с 1-м совпадением «или», второе значение «href» «это», а третье – «что?».

Причина, по которой я оставил первое совпадение «/», заключается в том, что вы можете использовать его для обратной ссылки позже для закрытия «/», поэтому это одно и то же.

См. Живой пример: http://www.rubular.com/r/jsKyK2b6do

preg_match_all ("/ (] >) (. ?) (</ a) /", $ contents, $ impmatches, PREG_SET_ORDER);

Он протестирован и получает все теги из любого html-кода.