JavaScript正则表达式中忽略特定捕获组的大小写。

12

在 PCRE 中,这将是一个有效的表达式。

/^\!(foo|bar) ((?i)ab|cd|ef|gh)$/

但在JavaScript正则表达式中,这是无效的。不幸的是,我不知道(?i)被称为什么,所以我在谷歌上遇到了一些问题。如何将此示例转换为JavaScript有效的格式?


实际上我想要做的:

查找所有以!foo!bar开头,并紧随一个空格并以abcdefgh结尾的行。后者应该是不区分大小写的。

!foo CD
!foo cD
!foo cd

所有这些都是有效的。虽然

!FOO cd !Foo cd

将是无效的。

2个回答

14
(?i)不区分大小写标志:从其放置在正则表达式内部的位置开始,它使得所有包含字母的字符类,例如[a-z],也匹配[A-Z](反之亦然)。这也适用于单个字母a(匹配aA)或序列ab(匹配ab,Ab,aB,AB)。
因此,您可以将其放置在正则表达式的开头/(?i)regex/(使其等效于js中的/regex/i),或者与其相反的标志(?-i)一起使用,以仅使正则表达式的某些部分不区分大小写
/^(?i)[a-z]{2}(?-i)[a-z]{2}/ 

以上正则表达式匹配2个大写或小写字符加上2个严格的小写字符。

匹配 ->   ROck, rOck, Rock
不匹配 -> ROCK, roCk, rOcK

你的PCRE正则表达式呢?

/^\!(foo|bar) ((?i)ab|cd|ef|gh)$/

如果您不介意匹配以!Foo,!FOo,!foO,!fOO,!BAR,!bar,...开头的字符串,您可以将标志放在外面,如下所示:
/^!(foo|bar) (ab|cd|ef|gh)$/i # you can also remove the escape from \! -> !

如果你希望得到与原始PCRE正则表达式 (/^!(foo|bar) ((?i)ab|cd|ef|gh)$/) 完全等效的内容,相应的 js 正则表达式会更难读懂。
/^!(foo|bar) ([Aa][Bb]|[Cc][Dd]|[Ee][Ff]|[Gg][Hh])$/

1
我尝试在Node中运行您的示例代码,但它返回SyntaxError: Invalid regular expression: /^(?i)[a-z]{2}(?-i)[a-z]{2}/: Invalid group。 - zudduz
1
@zudduz 感谢您让我澄清一个含糊不清的问题。您报告的正则表达式 /^(?i)[a-z]{2}(?-i)[a-z]{2}/PCRE 正则表达式。我在答案中引用它只是因为 OP 特别要求解释 (?i) PCRE 运算符。在 JavaScript 中等效的表达式是 /^[a-zA-Z]{2}[a-z]{2}/ - Giuseppe Ricupero

1
您可以从这里下载ECMAScript(JavaScript)文档。

https://www.ecma-international.org/publications/standards/Ecma-262.htm

RegExp在那里明确定义,并且不基于高级Perl规则。因此,不支持(?...)语法(请参见下面的更新,在较新的浏览器中可行)。

实现您想要的一种方法是对需要转换为大写/小写的每个字符使用[...]

(?i)ab

成为
[aA][bB]

这需要输入更多内容,但我不知道有什么更好的解决方案。
如果整个正则表达式可以是任何大小写,那么你可以使用标志:
/ab/i

但在你的例子中,这意味着"foo"也会被接受为"Foo"或"fOO"。

更新

JavaScript的新版本确实支持(<flag>?...)语法。

  • 如果RegExp对象的[[OriginalFlags]]内部槽包含"s",则DotAll为true;否则为false。
  • 如果RegExp对象的[[OriginalFlags]]内部槽包含"i",则IgnoreCase为true;否则为false。
  • 如果RegExp对象的[[OriginalFlags]]内部槽包含"m",则Multiline为true;否则为false。
  • 如果RegExp对象的[[OriginalFlags]]内部槽包含"u",则Unicode为true;否则为false。

因此,Giuseppe Ricupero的答案适用于新的浏览器、Node和React等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接