javascript - RegEx 替换返回意外结果,没有 .*

标签 javascript regex replace capture-group

我正在尝试创建一个执行以下转换的正则表达式:

  1. 苹果橙 > AO
  2. 加载模块 > LM
  3. 一个苹果橙 > O
  4. 加载模块 > M

我找到了合适的模式,但发现了一个奇怪的行为。这是我的初步尝试:

/^([A-Z])?[^ ]* ([A-Z])/

用这个表达式对第三个(和第四个)测试用例运行替换给了我一个令人惊讶的结果:

'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z])/,'$1$2')
> "Orange"

为什么令人惊讶?好吧,第一组显然不匹配,因为字符串不是以大写字母开头,但第二组只选择了一个单个大写字母:([A-Z]),不是后面的所有内容:([A-Z].*)

令我惊讶的是,在最后一个捕获组之后添加 .* 给了我正确的结果:

'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z]).*/,'$1$2')
> "O"

为什么会发生这种情况超出了我对 JS 和正则表达式的理解。我很高兴知道是什么黑魔法导致单个 [A-Z] 返回多个,甚至是一些小写字符。

这是一个可运行的演示:

var testCases = [
      'Apple Orange',
      'Load Module',
      'anApple Orange',
      'toLoad Module'
    ],
    badregex = /^([A-Z])?[^ ]* ([A-Z])/,
    goodregex = /^([A-Z])?[^ ]* ([A-Z]).*/;

document.onreadystatechange = function(n){
  if (document.readyState === "complete"){
      for (var i=0,l=testCases.length; i<l; i++){
        var p = document.createElement('p'),
            testCase = testCases[i];
        p.innerHTML = ""+testCase+" &gt; "+testCase.replace(badregex,'$1$2')
        document.body.appendChild(p);
      }
      document.body.appendChild(document.createElement('hr'));
      for (var i=0,l=testCases.length; i<l; i++){
        var p = document.createElement('p'),
            testCase = testCases[i];
        p.innerHTML = ""+testCase+" &gt; "+testCase.replace(goodregex,'$1$2')
        document.body.appendChild(p);
      }
  }
}

最佳答案

我愿意,

> "Apple Orange".replace(/(?:^|\s)([A-Z])|./g, "$1")
'AO'

不要把事情复杂化。只需捕获紧随空格或开头的所有大写字符即可。然后匹配所有剩余的字符。现在将所有匹配的字符替换为 $1 .请注意,所有匹配的字符都将替换为替换部分中存在的字符。

DEMO

为什么?

'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z])/,'$1$2')
> "Orange"
  • ([A-Z])?在开头检查可选的大写字母。哪有这回事。所以它捕获一个空字符串。
  • [^ ]*匹配零个或多个非空格字符。
  • <space>匹配一个空格。
  • ([A-Z])仅捕获 Orange 中的第一个字母。
  • 现在用 $1 替换所有匹配的字符-> 空字符串 $2 -> O会给你Orange

关于javascript - RegEx 替换返回意外结果,没有 .*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30740465/

相关文章:

php - 使用正则表达式验证类/方法名称

python - 如何通过正则表达式过滤 Pandas 中的行

javascript - str.replace 在 html 中不起作用

java - android - 在包含特殊字符的特定字符串上使用 replaceAll 时出现 java.lang.ArrayIndexOutOfBoundsException

javascript - 根据条件拆分 JavaScript 字符串

javascript - 上传文件 Angular.js FormData

javascript - Jest 中的模拟 shell 命令输出

php - codeigniter jquery 的自动完成功能不起作用,但没有错误

javascript 查找并替换文本区域中的整个单词

c# - Regex.Match 不适用于查找其他文本 C# 中包含的字符串