Попытка найти ссылки на странице.
мое регулярное выражение:
/<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 }
Также см:
На стороне: я уверен, что это дубликат, и вы можете найти ответ где-то здесь
Я согласен с 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-кода.