Joh*_*ica 27
#^[^\pL]+|[^\pL]+$#u
替换*为+.使用*结合$完全不是那么回事正如人们所期望的那样.在正则表达式引擎如何工作的奇怪结果中,X*$将找到两个匹配X*.使用+修复它.
[^\pL]*$
让我们看一下正则表达式的这一部分,这部分没有按预期工作.为什么它会把两个*字符串放在一些字符串的末尾?
---A---在替换第一组破折号后,请考虑第三个示例字符串:
*A---$
正则表达式引擎在这里找到正则表达式的匹配:
*A---$
  ^
并替换"---"为星号:
*A*$
  ^
然后它将其内部光标移动到替换字符串的右侧.
*A*$
   ^
它从此光标位置开始并查找另一个匹配项.它找到了一个!它找到了""- 空字符串!""由0或更多非字母([^\pL]*)组成,并且它锚定在字符串($)的末尾,因此它是有效匹配.它确实找到了空字符串,但这是允许的.
这是出乎意料的,因为它$再次匹配锚.这不是错的吗?它不应该$再次匹配,是吗?嗯,实际上,它应该,而且确实如此.它可以$再次匹配,因为$它不是输入字符串中的实际字符 - 它是零宽度断言.它不会被第一次更换"用完".$允许匹配两次.
因此,它""用星号"替换"空字符串.这就是为什么你最终得到两个星号.
*A**$
   ^
如果正则表达式引擎返回到步骤4,它将找到另一个空字符串并添加另一个星号.从概念上讲,那里有无数个空字符串.为避免这种情况,引擎不允许下一个匹配从与前一个匹配的位置开始.此规则使其无法进入无限循环.
正确的正则表达式是这样的:
$arr = preg_replace('#^[^\pL]+|[^\pL]+$#','*', 
           array('A','-A-','---A---','-+*A*+-','------------A------------'));
注意+而不是*.这将给出输出:
Array
(
    [0] => A
    [1] => *A*
    [2] => *A*
    [3] => *A*
    [4] => *A*
)
PS:请注意,由于A之前和之后没有非alpha字符这一事实,第一个元素将保持不变.