【发布时间】:2014-04-19 02:07:17
【问题描述】:
如果一个字符串存在但不是立即在另一个字符串之前,我似乎无法找到不返回匹配项的方法。
如果一个字符串存在于另一个字符串之前立即,我无法返回匹配项,如下所示。
$string = 'Stackoverflow hello world foobar test php';
$regex = "~(Stackoverflow).*?(?<!(test\s))(php)~i";
if(preg_match_all($regex,$string,$match))
print_r($match);
在这个例子中,如果我们有单词 Stackoverflow 和 php 我们想要返回一个匹配,但前提是单词 test(带有空格字符)在单词 php 之前不存在。
这不会返回任何好的结果。
现在让我说我想匹配 php 但前提是 foobar 这个词在 Stackoverflow 和 php 之间的某处不存在,我以为我可以做到以下几点。
$string = 'Stackoverflow hello world foobar test php';
$regex = "~(Stackoverflow).*?(?<!(foobar)).*?(php)~i";
if(preg_match_all($regex,$string,$match))
print_r($match);
(我已将字符串后面的负面外观更改为(foobar),并在后面添加了.*?)
我还想说,我不能总是知道foobar和php之间会存在什么词,有时没有,有时200个,但我确实有一些定位信息(在Stackoverflow之后和php之前)。
【问题讨论】:
-
.*?中的任何一个都可以绕过断言。您需要使用负前瞻来掩盖.任何占位符的所有可能位置。 -
@mario 所以我必须在 Stackoverflow 之后为每个字符重复这个 (?
-
"这不会返回任何好的结果。" == "一个太快的假设"
-
是的,基本上你将
.*?中的句点拆分为一个掩码匹配所有((?!foobar).),并用((?!xxx).)*?反复测试。它通常被认为是浪费的,因为断言适用于介于两者之间的每个字符。但对于简单的情况,它是相当可行的,PCRE 对其进行了优化。