preg_match在锚点上提取mailto

Ger*_*jan 2 php regex mailto anchor preg-match

我需要从带有正则表达式的mailto属性的锚点获取电子邮件地址.

这种模式: (.*)<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);
Run Code Online (Sandbox Code Playgroud)

那么为什么要在php中工作呢?

Gum*_*mbo 5

PHP的PCRE要求将正则表达式包装到分隔符中,该分隔符将模式与可选修饰符分开.在这种情况下,使用第一个非字母数字字符(即'),因此模式实际上是正确的(.*)<a (.*?)(.*) *href\=[,其余的被视为修饰符.这是一个无效的正则表达式,因为[没有正确转义,其余的也不是有效的修饰符.

正如其他人已经建议的那样,您可以通过'在正则表达式中转义分隔符的任何出现来修复此问题,或者选择不出现在正则表达式中的其他分隔符.

但除此之外,尝试使用正则表达式解析HTML非常容易出错.在你使用那么多的情况下.*也会导致可怕的性能行为(这只是由于正则表达式的处理方式).

更好地使用适当的HTML解析器返回可以像PHP的DOM库一样查询的DOM:

$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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • -1.回答具体问题,_then_讲述为什么DOM更好.无论我们多么认为有更好的方法,提问者理解新图书馆或快速重构他们的情况可能并非易事. (2认同)