使用先行否定断言的正则表达式

时间:2013-09-15 01:34:34

标签: php regex assertion lookahead

使用php我想根据匹配部分之后的部分是否包含某些字符来检测字符串中的某些内容。我想我可能需要使用前瞻性的否定断言,但它不能正常工作,因为我不能确定。例如:

$string = 'test somerandomURL><b>apple</b> peach orange';

我想要一个能够检测到第一个&gt;之前的所有内容的表达式只要<b>apple</b>没有紧跟第一个&gt;

我试过

if(preg_match("/test(.*)>(?!<b>apple<\/b>)(.*)/i",$string)){
echo 'true since <b>apple</b> does not follow > in string';
}else{
echo 'false since <b>apple</b> follows > in string';
}

当字符串在&gt;之后包含<b>apple</b>时它会按照我的预期和需要返回false,但是当我在&gt;之后将字符串更改为<b>peach</b>时而不是<b>apple</b>它仍然返回false,我需要它返回true。如果没有粗体标签,它似乎可以像我期望的那样工作。我有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您做错了一些事情,包括没有启用错误报告,因为您的()/不匹配需要转义。

第一个问题是。*贪婪。因此,在您的字符串中,它将匹配:test somerandomURL><b>apple</b>

通常情况下,解决方案是使.*?变得懒惰,但由于前瞻性为负,当发现苹果时,懒惰仍会使其与>匹配。

解决方案是一个否定的字符类。 [^>]*将匹配除>

之外的任何字符
/test([^>]*)>(?!<b>apple<\/b>)(.*)/i