我正在尝试创建一个执行以下转换的regualr表达式:
ifelse
> Apple Orange
AO
> Load Module
LM
> anApple Orange
O
> toLoad Module
我找到了合适的模式,但发现了一种奇怪的行为。这是我最初的尝试:
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]
答案 0 :(得分:2)
我愿意,
> "Apple Orange".replace(/(?:^|\s)([A-Z])|./g, "$1")
'AO'
不要复杂的事情。只需捕获存在于空格或开头的所有大写字符。然后匹配所有剩余的字符。现在用$1
替换所有匹配的字符。请注意,所有匹配的字符都将替换为替换部件中存在的字符。
为什么?
'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])?
是可选的且不匹配且$2
为O
所以您将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