我在编写非贪婪的正则表达式语句时遇到了麻烦。
这是我的字符串:
<strong>name</strong><strong>address</strong>mailto:blabla@email.com
这是我的正则表达式查询:
<strong>(.*?)</strong>.*?([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})
问题是我需要地址,而不是字符串中的名称。所以我需要正则表达式查询是非贪婪的,并采取最接近的<strong></strong>
而不是最远的。{/ p>
我的搜索字符串中还有多个这样的实例,因此它必须一次匹配多个实例,而不是仅仅在它前面添加.*
(贪婪)的东西。
所以它必须匹配所有这些实例,并提取地址,而不是名称:
<strong>name</strong><strong>address1</strong>mailto:blabla@email.com
<strong>name</strong><strong>address2</strong>mailto:blabla@email.com
<strong>name</strong><strong>address3</strong>mailto:blabla@email.com
<strong>name</strong><strong>address4</strong>mailto:blabla@email.com
提前致谢!
答案 0 :(得分:2)
首先,正则表达式是匹配HTML的次优工具(这是一个很好的例子,为什么会这样)。如果你知道如何使用解析器,你会对解析器更开心(也许其中一位PHP大师可以推荐一个)。
话虽如此,使用正则表达式的更好方法可能是明确匹配(并丢弃)第一个<strong>
标记:
<strong>.*?</strong><strong>(.*?)</strong>.*?([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})
这绝不是一个好的,可靠的防弹解决方案,但至少它适用于您的样本数据。
或者,如果您可以更具体地说明相关标签之间/之后允许的内容,那么:
<strong>([^<>]*)</strong>(?:mailto:)?([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})
答案 1 :(得分:0)
不要使用正则表达式来解析HTML。
答案 2 :(得分:0)
查看您的测试数据,以下是我推断的规则:如果......
mailto:
,AND 然后这个经过测试的代码可以解决这个问题:
$re = '%
# Capture name and address in <strong> element then email.
<strong[^>]*>\s*([^<>]+)</strong\s*>\s* # $1: Name.
<strong[^>]*>\s*([^<>]+)</strong\s*>\s* # $2: Address.
(mailto:\S+) # $3: Email.
%ix';
$count = preg_match_all($re, $text, $matches);
if ($count) {
printf("%d matches found:\n", $count);
print_r($matches);
for ($i = 0; $i < $count; ++$i) {
printf("Match %d: Name: \"%s\", Address: \"%s\", Email: \"%s\":\n",
$i + 1, $matches[1][$i], $matches[2][$i], $matches[3][$i]);
}
} else {
printf("No matches found.\n");
}