php - 固定长度的正则表达式后视提示可变长度的后视

标签 php regex

这是我要运行的代码:

$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/

相关文章:

java - 使用 String.split 时转义逗号

regex - 正则表达式范围 a-Z 中将包含哪些字符?

C# 正则表达式 匹配整个单词,包含特殊字符

php - 来自不同表的用户积分

php - 如何更改 WordPress 中的图片作者?

php - 如何获取变量中包含@的std类对象数组?

javascript - Node : RegExp returns nothing

c# - 使用正则表达式识别文本开头和结尾的选定文本#

php - MySQLi 从表中选择主题标签

php 在有奖竞赛中获得积极的随机响应