我需要从带有正则表达式的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);
那么为什么要在php中工作呢?
答案 0 :(得分:5)
PHP’s PCRE要求将正则表达式包装到delimiters中,以便将模式与可选modifiers分开。在这种情况下,使用第一个非字母数字字符(即'
),因此模式实际上只是(.*)<a (.*?)(.*) *href\=[
,其余的被视为修饰符。这是一个无效的正则表达式,因为[
未正确转义,其余的也不是有效的修饰符。
正如其他人已经建议的那样,你可以通过在正则表达式中转义任何出现的分隔符'
来解决这个问题,或者选择一个不出现在正则表达式中的不同分隔符。
但除此之外,尝试使用正则表达式解析HTML非常容易出错。在你的情况下,使用那么多.*
也会导致一种可怕的性能行为(这只是由于正则表达式的处理方式)。
更好地使用适当的HTML解析器来返回可以像PHP’s DOM library一样查询的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);
}
}
}
答案 1 :(得分:1)
您的分隔符是引用'
,正则表达式中有一些实例:
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);
^ ^
逃避它们(即:\'
)或更改分隔符。
答案 2 :(得分:0)
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 = "";
}