Вопрос

Мне нужно получить адрес электронной почты с якоря с атрибутом Mailto с Regex.

Этот шаблон: (.*)<a\s(.*?)(.*)\s*href\=['"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['"]>(.*)</a>(.*)

Работает в тренере Regex, хотя он не работает с PHP.

Код:

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);

Так почему же, что он работает в PHP?

Это было полезно?

Решение

PHRE PHRE требуют, чтобы регулярное выражение было завернуто в разделители это отделить шаблон из необязательного модификаторы. Отказ В этом случае используется первый не буквенно-цифровой символ (т.е. ') так что шаблон на самом деле просто (.*)<a (.*?)(.*) *href\=[ И остальные рассматриваются как модификаторы. И это неверное регулярное выражение как [ неправильно избежается, а остальные не являются действительными модификаторами.

Как и другие уже предложили, вы можете исправить это, избегая любого возникновения разделителя ' Внутри регулярного выражения или выберите другой разделитель, который не отображается в регулярном выражении.

Но кроме того, пытаясь анализировать HTML с регулярными выражениями, очень подвержены ошибкам. В вашем случае, используя это много .* Также приведет к ужасному поведению эффективности (он только из-за того, насколько регулярно обрабатываются регулярные выражения).

Лучше Используйте правильный Parser HTML, который возвращает DOM, который может быть запрошен, как Библиотека Dom 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);
        }
    }
}

Другие советы

Ваш разделитель - цитата ', И есть некоторые экземпляры этого в 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);
                                      ^                                              ^

Избежать их (т.е. \') Или измените свой разделитель.

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 = "";
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top