繁体   English   中英

正则表达式替换返回不带。*的意外结果

[英]RegEx replace returns unexpected result without .*

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

  1. Apple Orange > AO
  2. Load Module > LM
  3. anApple Orange > O
  4. toLoad Module > M

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

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

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

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

为什么这么惊讶? 好了,第一组明显不匹配,因为字符串不以大写字母开头,但第二组只选择一个大写字母: ([AZ])之后不是一切吧: ([AZ].*)

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

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

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

这是一个可运行的演示:

 var testCases = [ 'Apple Orange', 'Load Module', 'anApple Orange', 'toLoad Module' ], badregex = /^([AZ])?[^ ]* ([AZ])/, goodregex = /^([AZ])?[^ ]* ([AZ]).*/; 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 请注意,所有匹配的字符都替换为替换部分中存在的字符。

演示

为什么?

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

您的第一个示例与anApple O匹配。 $1为空是因为^([AZ])? 是可选的,不匹配和$2O所以你更换anApple O通过O在字符串中anApple Orange ,这将导致Orange

除了使用带有复杂正则表达式的replace ,您还可以使用带有match非常简单的正则表达式,并使用join获得所需的输出:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM