我一直在使用这个普通快递(可能在几年前的stackoverflow上找到)来转换PHP中的mailto标签:
preg_match_all("/<a([ ]+)href=([\"']*)mailto:(([[:alnum:]._\-]+)@([[:alnum:]._\-]+\.[[:alnum:]._\-]+))([\"']*)([[:space:][:alnum:]=\"_]*)>([^<|@]*)(@?)([^<]*)<\/a>/i",$content,$matches);
我传递了$content = '<a href="mailto:name@domain.com">somename@domain.com</a>'
返回这些匹配的部分:
0 <a href="mailto:name@domain.com">somename@domain.com</a>
1
2 "
3 name@domain.com
4 name
5 domain.com
6 "
7
8 somename
9 @
10 domain.com
使用示例:<a href="send.php?user=$matches[4][0]&dom=$matches[5][0]">ucwords($matches[8][0])</a>
我的问题是,某些链接包含嵌套标记。由于preg表达式正在寻找“&lt;”得到件8,9,10和嵌套标签扔掉它......
实施例:
<a href="mailto:name@domain.com"><span><b>somename@domain.com</b></span></a>
我需要忽略嵌套标签,只需提取“某个名称”片段:
match part 8 = <span><b>
match part 9 = somename
match part 10 = @
match part 11 = domain.com
match part 12 = </b></span>
我试图通过调整([^<|@]*)(@?)([^<]*)
让它工作,但我找不到匹配或忽略嵌套标记的正确语法。
答案 0 :(得分:1)
你可以直接替换&lt; a&gt;之间的整个匹配。标记为.*?
。将([^<|@]*)(@?)([^<]*)
替换为(.*?)
,它将包含&lt; a&gt;内的所有内容。标签包括嵌套标签。您可以使用striptags或其他正则表达式删除嵌套标签。
但是,正则表达式在html嵌套标签上并不是很好。你最好使用像DOMDocument这样的东西,它完全用于解析html。类似的东西:
<?php
$DOM = new DOMDocument();
$DOM->loadXML('<a href="mailto:name@domain.com"><span><b>somename@domain.com</b></span></a>');
$list = $DOM->getElementsByTagName('a');
foreach($list as $link){
$href = $link->getAttribute('href');
$text = $link->nodeValue;
//only match if href starts with mailto:
if(stripos($href, 'mailto:') === 0){
var_dump($href);
var_dump($text);
}
}
答案 1 :(得分:0)
你可以尝试这种模式:
$pattern = '~\bhref\s*+=\s*+(["\'])mailto:\K(?<mail>(?<name>[^@]++)@(?<domain>.*?))\1[^>]*+>(?:\s*+</?(?!a\b)[^>]*+>\s*+)*+(?<content>[^<]++)~i';
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
echo '<pre>' . print_r($matches, true) . '</pre>';
您可以像这样访问您的数据:
echo $matches[0]['name'];
答案 2 :(得分:0)
要仅访问链接中的部分,请尝试
[^>]*>([^>]+)@.*
你需要的应该是结果的第一组。
答案 3 :(得分:0)
试试这个正则表达式
/^(<.*>)(.*)(@)/
/^/
- 字符串开头
/(<.*>)/
- 第一个匹配组,以&lt;开头然后介于两者之间,直到它击中&gt;
/(.*)(@)/
- 匹配括号内的任何内容