Pergunta

Preciso obter o endereço de e -mail de uma âncora com um atributo de e -mail com regex.

esse padrão: (.*)<a\s(.*?)(.*)\s*href\=['"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['"]>(.*)</a>(.*)

Funciona no Regex Coach, embora não funcione com o PHP.

Código:

preg_match("'(.*)<a (.*?)(.*) *href\=['\"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['\"]>(.*)</a>(.*)'si", "<a href=\"mailto:someemail@ohio.com\"">Some email</a>", $matches);

print_r($matches);

Então, por que funciona no PHP?

Foi útil?

Solução

PCRE do PHP exigir que a expressão regular seja envolvida delimitadores que separam o padrão de opcional modificadores. Nesse caso, o primeiro personagem não alfanumérico é usado (ou seja, ') então o padrão é realmente apenas (.*)<a (.*?)(.*) *href\=[ e o restante é tratado como modificadores. E essa é uma expressão regular inválida como o [ não é escapar corretamente e o restante também não são modificadores válidos.

Como os outros já sugeriram, você pode consertar isso escapar de qualquer ocorrência do delimitador ' Dentro da expressão regular ou escolha um delimitador diferente que não apareça na expressão regular.

Mas, além disso, tentar analisar HTML com expressões regulares é muito propenso a erros. No seu caso usando tantos .* também resultará em um comportamento de desempenho horrível (é apenas devido à maneira como as expressões regulares são processadas).

Melhor usar um analisador HTML adequado que retorne um DOM que pode ser consultado como Biblioteca Dom do PHP:

$doc = new DomDocument();
$doc->loadHTML($str);
foreach ($doc->getElementsByTagName("a") as $a) {
    if ($a->hasAttribute("href")) {
        $href = trim($a->getAttribute("href"));
        if (strtolower(substr($href, 0, 7)) === 'mailto:') {
            $components = parse_url($href);
        }
    }
}

Outras dicas

Seu delimitador é uma citação ', e há alguns casos no regex:

preg_match("'(.*)<a (.*?)(.*) *href\=['\"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['\"]>(.*)</a>(.*)'si", "<a href=\"mailto:someemail@ohio.com\"">Some email</a>", $matches);
                                      ^                                              ^

Escape deles (ou seja: \') ou altere seu delimitador.

if (preg_match('#<a\s.*?href=[\'"]mailto:([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6})[\'"].*?>.*?</a>#i', $subject, $regs)) {
    $result = $regs[0];
} else {
    $result = "";
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top