在 PHP 和 Java 中,我将 /^[^\pL]*|[^\pL]*$/
应用于 -A-
并且我得到了 *A**
。我应用了对称图案并得到了不对称的结果!为什么?我想知道为什么它的输出不是*A*
?
模式说字符串末尾除了字母以外的所有东西都应该用*
替换,它也是贪心的,应该把所有非字母的东西一起替换。
请注意,在 RegexBuddy 中我得到 *A*
,这正是我所期望的。
更新:我简化了问题以集中我的主要关注点。
最佳答案
#^[^\pL]+|[^\pL]+$#u
将 *
替换为 +
。将 *
与 $
结合使用并不像人们预期的那样有效。正则表达式引擎工作方式的一个奇怪结果是,X*$
将找到两个 匹配X*
。使用 +
修复它。
说明
[^\pL]*$
让我们看看正则表达式的这一部分,它没有按预期工作。为什么它在某些字符串的末尾放置两个 *
?
在第一组破折号被替换后,考虑第三个示例字符串
---A---
:*A---$
正则表达式引擎在此处找到正则表达式的匹配项:
*A---$ ^
并将
“---”
替换为星号:*A*$ ^
然后它将其内部光标移动到替换字符串的右侧。
*A*$ ^
它从这个光标位置开始寻找另一个匹配项。它找到了一个!它找到了
""
——空字符串!""
由 0 个或多个非字母 ([^\pL]*
) 组成,它锚定在字符串的末尾 ($
), 所以这是一个有效的匹配。它确实找到了空字符串,但这是允许的。这是意外的,因为它再次匹配了
$
anchor 。是不是错了?它不应该再次匹配$
,不是吗?好吧,实际上,它应该而且确实如此。它可以再次匹配$
,因为$
不是输入字符串中的实际字符——它是一个零宽度断言。它不会被第一次更换“用完”。$
允许匹配两次。因此,它用星号“替换”了空字符串
""
。这就是为什么你最后有两个星号。*A**$ ^
如果正则表达式引擎返回到第 4 步,它会找到另一个空字符串并添加另一个星号。从概念上讲,那里有无数个空字符串。为避免这种情况,引擎不允许下一场比赛在与上一场比赛相同的位置开始。这条规则防止它进入无限循环。
关于java - 替换文本末尾的额外字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15706512/