如果字符串存在但不是在另一个字符串之前,我似乎无法找到一种不返回匹配的方法.
如果字符串紧跟在另一个字符串之前,我将无法返回匹配项,具有以下内容.
$string = 'Stackoverflow hello world foobar test php';
$regex = "~(Stackoverflow).*?(?<!(test\s))(php)~i";
if(preg_match_all($regex,$string,$match))
print_r($match);
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我们想要返回一个匹配,如果我们有单词Stackoverflow和php,但只有在单词php之前不存在单词test(带空格字符).
这不会返回任何好的结果.
让我们现在说我想匹配php但只有在Stackoverflow和php之间的某个地方不存在foobar这个词时,我假设我可以做以下事情.
$string = 'Stackoverflow hello world foobar test php';
$regex = "~(Stackoverflow).*?(?<!(foobar)).*?(php)~i";
if(preg_match_all($regex,$string,$match))
print_r($match);
Run Code Online (Sandbox Code Playgroud)
(我已将字符串背后的负面效果更改为(foobar),并添加.*?之后)
我还想说,我不能总是知道foobar和php之间会有什么词,有时候会有,有时候200,但我确实有一些定位信息(在Stackoverflow之后和php之前).
您的第二个正则表达式有效,因为“foobar”只能作为一个正则表达式的一部分出现.*?。具体来说,第一个.*?将匹配空字符串“”,第二个将匹配“hello world foobar test”,它前面确实没有“foobar”!
为了获得所需的结果,一种方法是查看每个字符并确保它不是“f”,或者如果它是“f”但后面没有“o”,或者如果它是一个“f”后跟一个“o”,后面没有另一个“o”,等等。
这将为您留下:
$string = 'Stackoverflow hello world foobar test php';
$regex = "~(Stackoverflow)(?:[^f]|f[^o]|fo[^o]|foo[^b]|foob[^a]|fooba[^r])*?(php)~i";
if(preg_match_all($regex,$string,$match))
print_r($match);
Run Code Online (Sandbox Code Playgroud)
性能更新
我对我的建议和 Ron 的建议进行了基准测试,发现虽然 Perl 没有显着差异,但他的 PCRE 快了近 50%。
| 归档时间: |
|
| 查看次数: |
885 次 |
| 最近记录: |