RegEx replace不返回意外结果。*

时间:2015-06-09 18:53:16

标签: javascript regex replace capture-group

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

  1. ifelse> Apple Orange
  2. AO> Load Module
  3. LM> anApple Orange
  4. O> toLoad Module
  5. 我找到了合适的模式,但发现了一种奇怪的行为。这是我最初的尝试:

    M

    使用此表达式在第三个(和第四个)测试用例上运行替换会给出一个令人惊讶的结果:

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

    为什么这令人惊讶?好吧,第一组显然不匹配,因为字符串不以大写字母开头,但第二组只选择大写字母:'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z])/,'$1$2') > "Orange" ,而不是后面的所有内容: ([A-Z])

    令我惊讶的是,在最后一个捕获组之后立即添加([A-Z].*)给了我正确的结果:

    .*

    为什么会发生这种情况超出了我对JS和正则表达式的理解。我很高兴知道什么样的黑魔法导致单'anApple Orange'.replace(/^([A-Z])?[^ ]* ([A-Z]).*/,'$1$2') > "O" 返回多个,甚至是一些小写字符。

    这是一个可运行的演示:

    [A-Z]

3 个答案:

答案 0 :(得分:2)

我愿意,

> "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 - &gt;空字符串$2 - &gt; O将为您提供Orange

答案 1 :(得分:1)

您的第一个示例与anApple O匹配。 $1为空,因为^([A-Z])?是可选的且不匹配且$2O所以您将anApple O替换为字符串O { {1}}这将导致anApple Orange

答案 2 :(得分:1)

您可以使用带有replace的非常简单的正则表达式并使用match来获得所需的输出,而不是将join与复杂的正则表达式一起使用:

'anApple Orange'.match(/\b([A-Z])/g).join('')
//=> O

'Apple Orange'.match(/\b([A-Z])/g).join('')
//=> AO