负面后瞻性正则表达式捕获的问题

时间:2011-07-21 23:15:45

标签: php regex negative-lookbehind

我尝试匹配电子邮件地址,但仅当它们不在“mailto:”之前。我试试这个正则表达式:

"/(?<!mailto:)[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})/"

对此字符串: '<a href="mailto:someemail@domain.com">EMAIL</a> ... otheremail@domain.com '

我希望只能抓住'otheremail@domain.com',但我也会收到'omeemail@domain.com' - 请参阅's'。我想知道这里有什么问题。在lookbehind断言之后,我不能拥有正常的正则表达式吗?

我在PHP中的整个示例如下:

$testString = '<a href="mailto:someemail@domain.com">EMAIL</a>  ...   otheremail@domain.com ';
$pattern = "/(?<!mailto:)[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})/";
preg_match_all($pattern, $testString, $matches);
echo('<pre>');print_r($matches);echo('</pre>');

谢谢!

3 个答案:

答案 0 :(得分:5)

因为在s之后有一个与您的正则表达式匹配的字符串omeemail@domain.com,并且因为s几乎不匹配mailto:。在那里获得单词边界将适用于大多数情况:

变化:

(?<!mailto:)

要:

(?<!mailto:)\b

旁注:使用example.com作为示例,domain.com由实际公司拥有。

答案 1 :(得分:2)

它尝试匹配“someemail @”,但失败,因为它紧接着是“mailto:”,因此它尝试匹配“omeemail @”,这成功,因为它不会立即在“mailto:”之后。

编辑:它认为将(?<!mailto:)更改为(?!mailto:)效果最佳。

@Wrikken:正则表达式允许“。”在电子邮件地址中,但如果您有(?<!mailto:)\b,则“mailto:some.email @”将与“email @”匹配。

答案 2 :(得分:0)

因此,通过@Wrikken和@MRAB的提示,我们得出了最终的正在运行的正则表达式:
"/(?<!mailto:)(?<=^|[^A-Za-z0-9_.+@-])[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})/"

重要的是在负面观察后使用前瞻作为“电子邮件边界”。