Respostas:
Regex confiável para HTML é difícil . Aqui está como fazer isso com DOM :
$dom = new DOMDocument;
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('a') as $node) {
echo $dom->saveHtml($node), PHP_EOL;
}
O código acima iria encontrar e produzir o "outerHTML" de todos os A
elementos da $html
string.
Para obter todos os valores de texto do nó, você faz
echo $node->nodeValue;
Para verificar se o href
atributo existe, você pode fazer
echo $node->hasAttribute( 'href' );
Para obter o href
atributo, você faria
echo $node->getAttribute( 'href' );
Para alterar o href
atributo, você faria
$node->setAttribute('href', 'something else');
Para remover o href
atributo que você faria
$node->removeAttribute('href');
Você também pode consultar o href
atributo diretamente com 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
}
Veja também:
Em uma nota: tenho certeza de que é uma duplicata e você pode encontrar a resposta em algum lugar aqui
Eu concordo com Gordon, você DEVE usar um analisador de HTML para analisar HTML. Mas se você realmente deseja uma regex, pode tentar esta:
/^<a.*?href=(["\'])(.*?)\1.*$/
Este partidas <a
no início da cadeia de caracteres, seguido por um número qualquer de qualquer carvão animal (não ávido) .*?
, em seguida, href=
seguido pela ligação rodeado por um ou outro "
ou'
$str = '<a title="this" href="that">what?</a>';
preg_match('/^<a.*?href=(["\'])(.*?)\1.*$/', $str, $m);
var_dump($m);
Resultado:
array(3) {
[0]=>
string(37) "<a title="this" href="that">what?</a>"
[1]=>
string(1) """
[2]=>
string(4) "that"
}
O padrão que você deseja procurar seria o padrão de âncora do link, como (algo):
$regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/";
por que você simplesmente não combina
"<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);
?>
então
$ php test.php
array(2) {
[0]=>
array(1) {
[0]=>
string(27) "<a title="this" href="that""
}
[1]=>
array(1) {
[0]=>
string(4) "that"
}
}
que funciona. Acabei de remover as primeiras chaves de captura.
preg_match_all("/<a.*?href\s*=\s*['\"](.*?)['\"]/", $str, $res, PREG_SET_ORDER);
fim de capturar corretamente todos os valores href no usoforeach($res as $key => $val){echo $val[1]}
Para quem ainda não conseguiu as soluções muito fáceis e rápidas usando SimpleXML
$a = new SimpleXMLElement('<a href="www.something.com">Click here</a>');
echo $a['href']; // will echo www.something.com
Está funcionando para mim
Não tenho certeza do que você está tentando fazer aqui, mas se você está tentando validar o link, olhe em filter_var do PHP ()
Se você realmente precisa usar uma expressão regular, verifique esta ferramenta, ela pode ajudar: http://regex.larsolavtorvik.com/
Usando seu regex, eu o modifiquei um pouco para atender às suas necessidades.
<a.*?href=("|')(.*?)("|').*?>(.*)<\/a>
Eu pessoalmente sugiro que você use um analisador de HTML
EDIT: Testado
<a title="this" href="that">what?</a>
Teste rápido: <a\s+[^>]*href=(\"\'??)([^\1]+)(?:\1)>(.*)<\/a>
parece funcionar, com a primeira correspondência sendo "ou ', a segunda o' href 'valor' que 'e a terceira o' o quê? '
A razão pela qual deixei a primeira correspondência de "/ 'lá é que você pode usá-la para referenciá-la posteriormente para o fechamento" /', então é a mesma coisa.
Veja o exemplo ao vivo em: http://www.rubular.com/r/jsKyK2b6do
preg_match_all ("/ (] >) (. ?) (</ a) /", $ contents, $ impmatches, PREG_SET_ORDER);
Ele é testado e busca todas as tags de qualquer código html.
O seguinte está funcionando para mim e retorna href
e value
da tag âncora.
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]
);
}
}
A matriz multidimensional chamada $urls
contém agora submatrizes associativas que são fáceis de usar.