java - 替换文本末尾的额外字符

标签 java php regex pcre

在 PHP 和 Java 中,我将 /^[^\pL]*|[^\pL]*$/ 应用于 ‍‍‍-A- 并且我得到了 *A**。我应用了对称图案并得到了不对称的结果!为什么?我想知道为什么它的输出不是*A*

模式说字符串末尾除了字母以外的所有东西都应该用*替换,它也是贪心的,应该把所有非字母的东西一起替换。

请注意,在 RegexBuddy 中我得到 *A*,这正是我所期望的。

更新:我简化了问题以集中我的主要关注点。

最佳答案

#^[^\pL]+|[^\pL]+$#u

* 替换为 +。将 *$ 结合使用并不像人们预期的那样有效。正则表达式引擎工作方式的一个奇怪结果是,X*$ 将找到两个 匹配X*。使用 + 修复它。

说明

[^\pL]*$

让我们看看正则表达式的这一部分,它没有按预期工作。为什么它在某些字符串的末尾放置两个 *

  1. 在第一组破折号被替换后,考虑第三个示例字符串 ---A---:

    *A---$
    
  2. 正则表达式引擎在此处找到正则表达式的匹配项:

    *A---$
      ^
    
  3. 并将 “---” 替换为星号:

    *A*$
      ^
    
  4. 然后它将其内部光标移动到替换字符串的右侧。

    *A*$
       ^
    
  5. 它从这个光标位置开始寻找另一个匹配项。它找到了一个!它找到了 ""——空字符串! "" 由 0 个或多个非字母 ([^\pL]*) 组成,它锚定在字符串的末尾 ($), 所以这是一个有效的匹配。它确实找到了空字符串,但这是允许的。

    这是意外的,因为它再次匹配了 $ anchor 。是不是错了?它不应该再次匹配 $ ,不是吗?好吧,实际上,它应该而且确实如此。它可以再次匹配 $,因为 $ 不是输入字符串中的实际字符——它是一个零宽度断言。它不会被第一次更换“用完”。 $ 允许匹配两次。

  6. 因此,它用星号“替换”了空字符串 ""。这就是为什么你最后有两个星号。

    *A**$
       ^
    
  7. 如果正则表达式引擎返回到第 4 步,它会找到另一个空字符串并添加另一个星号。从概念上讲,那里有无数个空字符串。为避免这种情况,引擎不允许下一场比赛在与上一场比赛相同的位置开始。这条规则防止它进入无限循环。

关于java - 替换文本末尾的额外字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15706512/

相关文章:

php - 如何处理 BrainTree 中的 Webhooks

c# - 从字符串中转义\x

javascript - 电话号码格式的正则表达式(不超过 10 位数字),不接受 0 或 1 作为第一个数字

java - 如何在 java 中读取 Excel (.xlsx) 文件?

java - 如何从选择查询的结果集中创建 Java 对象?

php - 无法在 Ubuntu 18.10 LEMP 堆栈上安装 Laravel?

PHP session 超时

javascript - 执行 JavaScript 正则表达式替换时如何转义捕获组 $N 后跟整数?

java - "Chaining"两个 Controller ?

java - Java中的泛型方法