这是我要运行的代码:
$str = 'a,b,c,d';
return preg_split('/(?<![^\\\\][\\\\]),/', $str);
如您所见,这里使用的正则表达式是:
/(?<![^\\][\\]),/
这是一个简单的固定长度负向后视,用于“前面是不是反斜杠的东西,然后是反斜杠的东西!”。
这个正则表达式在 http://www.phpliveregex.com 上工作得很好
但是当我去实际尝试运行上面的代码时,我被吐出错误:
Warning: preg_split() [function.preg-split]: Compilation failed: lookbehind assertion is not fixed length at offset 13
更糟糕的是,一位程序员同事在他的 5.4.24 PHP 服务器上测试了代码,并且运行良好。
这让我相信我的问题与我的服务器配置有关,我无法控制它。有人告诉我我的 PHP 版本是 5.2.*
preg_replace() 是否有任何可能不会出现此问题的解决方法/替代方案?
最佳答案
该问题是由PCRE 6.7 修复的bug 引起的。引用 the changelog :
A negated single-character class was not being recognized as fixed-length in lookbehind assertions such as
(?<=[^f])
, leading to an incorrect compile error"lookbehind assertion is not fixed length"
PCRE 6.7 在 PHP 5.2.0 中引入,2006 年 11 月。由于您仍然有这个错误,这意味着它不在您的服务器上 - 因此对于基于 preg-split 的解决方法,您必须使用没有负字符类的模式。例如:
$patt = '/(?<!(?<!\\\\)\\\\),/';
// or...
$patt = '/(?<![\x00-\x5b\x5d-\xFF]\x5c),/';
但是,我发现整个方法有点奇怪:如果,
怎么办?符号前面正好是三个反斜杠?还是五个?还是奇数个?这种情况下的逗号应被视为“转义”,但显然您不能创建可变长度的后视表达式来涵盖这些情况。
转念一想,可以使用 preg_match_all
相反,使用常见的交替技巧来覆盖转义符号:
$str = 'e ,a\\,b\\\\,c\\\\\\,d\\\\';
preg_match_all('/(?:[^\\\\,]|\\\\(?:.|$))+/', $str, $matches);
var_dump($matches[0]);
Demo .
我真的认为我涵盖了这里的所有问题,那些尾部斜线是一个 killer )
关于php - 固定长度的正则表达式后视提示可变长度的后视,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25774517/