funzione preg_match per estrarre mailto sull'ancoraggio
-
27-09-2019 - |
Domanda
Ho bisogno di ottenere l'indirizzo e-mail da un ancoraggio con un mailto attributo con espressioni regolari.
questo schema: (.*)<a\s(.*?)(.*)\s*href\=['"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['"]>(.*)</a>(.*)
Lavori in pullman regex se non lavorare con PHP.
Codice:
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);
Allora perché doenst funzionare in php?
Soluzione
di PHP richiede l'espressione regolare per essere avvolto nel delimitatori che separano il modello da optional modificatori . In questo caso viene utilizzato il primo carattere non alfanumerico (cioè '
) in modo che il modello è in realtà solo (.*)<a (.*?)(.*) *href\=[
e il resto sono trattati come modificatori. E questa è un'espressione regolare non valida come [
non è correttamente sfuggito e il resto non sono modificatori validi nessuno dei due.
Mentre gli altri hanno già suggerito, è possibile risolvere questo problema in fuga qualsiasi occorrenza del '
delimitatore all'interno della espressione regolare o scegliere un delimitatore diverso che non appare nelle espressioni regolari.
Ma oltre a questo, cercando di analizzare HTML con le espressioni regolari è molto soggetto ad errori. In caso utilizzando si che molti .*
comporterà anche un comportamento orribile prestazioni (è solo a causa di come le espressioni regolari vengono elaborati).
Meglio utilizzare una corretta parser HTML che restituisce un DOM che può essere interrogato come biblioteca DOM di 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);
}
}
}
Altri suggerimenti
Il delimitatore è un '
citazione, e ci sono alcune istanze di esso nella 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);
^ ^
sfuggire loro (cioè .: \'
) o cambiare delimitatore.
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 = "";
}