107

我见过很多使整个正则表达式不区分大小写的例子。我想知道的是只有部分表达式不区分大小写。

例如,假设我有一个这样的字符串:

fooFOOfOoFoOBARBARbarbarbAr

如果我想匹配所有出现的“foo”而不考虑大小写,但我只想匹配大写的“BAR”怎么办?

理想的解决方案是适用于正则表达式风格的东西,但我也有兴趣听到特定语言的东西(谢谢Espo

编辑

Espo 提供的链接非常有帮助。那里有一个很好的例子,关于在表达式中打开和关闭修饰符。

对于我的人为示例,我可以执行以下操作:

(?i)foo*(?-i)|BAR

这使得匹配只对匹配的 foo 部分不区分大小写。

这似乎在大多数正则表达式实现中都有效,除了 Javascript、Python 和其他一些(正如 Espo 提到的)。

我想知道的大的(Perl、PHP、.NET)都支持内联模式更改。

4

5 回答 5

93

Perl 允许您使用 (?i:) 模式修饰符使您的正则表达式的一部分不区分大小写。

现代正则表达式风格允许您仅将修饰符应用于正则表达式的一部分。如果在正则表达式的中间插入修饰符 (?ism),则修饰符仅适用于正则表达式中修饰符右侧的部分。您可以通过在它们前面加上减号来关闭模式。减号后的所有模式都将关闭。例如 (?i-sm) 打开不区分大小写,关闭单行模式和多行模式。

并非所有的正则表达式都支持这一点。JavaScript 和 Python 将所有模式修饰符应用于整个正则表达式。它们不支持 (?-ismx) 语法,因为当模式修饰符应用于整个正则表达式时,关闭选项是没有意义的。所有选项默认关闭。

您可以快速测试您使用的正则表达式如何处理模式修饰符。正则表达式 (?i)te(?-i)st 应该匹配 test 和 TEst,但不匹配 teST 或 TEST。

来源

于 2008-09-04T12:35:25.520 回答
9

确实可以依赖内联修饰符,如为正则表达式的一部分打开和关闭模式中所述:

正则表达式(?i)te(?-i)st应匹配 test and TEst,但不匹配teSTor TEST

但是,更受支持的功能是(?i:...)内联修饰符组(请参阅Modifier Spans)。语法是(?i:,然后是您想要不区分大小写的模式,然后是).

(?i:foo)|BAR

相反:如果您的模式是使用不区分大小写的选项编译的,并且您需要使正则表达式的一部分区分大小写,则在:-之后添加。?(?-i:...)

各种语言中的示例使用(用尖括号括起匹配项):

  • - preg_replace("~(?i:foo)|BAR~", '<$0>', "fooFOOfOoFoOBARBARbarbarbAr")(演示)
  • - re.sub(r'(?i:foo)|BAR', r'<\g<0>>', 'fooFOOfOoFoOBARBARbarbarbAr')( demo ) (注意Python从 Python 3.6 开始re支持内联修饰符组)
  • # / / (演示Regex.Replace("fooFOOfOoFoOBARBARbarbarbAr", "(?i:foo)|BAR", "<$&>"))
  • - "fooFOOfOoFoOBARBARbarbarbAr".replaceAll("(?i:foo)|BAR", "<$0>")(演示)
  • - $s =~ s/(?i:foo)|BAR/<$&>/g(演示)
  • - "fooFOOfOoFoOBARBARbarbarbAr".gsub(/(?i:foo)|BAR/, '<\0>')演示
  • - gsub("((?i:foo)|BAR)", "<\\1>", "fooFOOfOoFoOBARBARbarbarbAr", perl=TRUE)(演示)
  • -"fooFOOfOoFoOBARBARbarbarbAr".replacingOccurrences(of: "(?i:foo)|BAR", with: "<$0>", options: [.regularExpression])
  • - (使用 RE2) - regexp.MustCompile(`(?i:foo)|BAR`).ReplaceAllString( "fooFOOfOoFoOBARBARbarbarbAr", `<${0}>`)演示

不支持 std::regex

在这些情况下,您可以将两个字母变体放入一个字符类(不是一个组,请参阅为什么字符类比交替更快?)。例子:

  • - sed -E 's/[Ff][Oo][Oo]|BAR/<&>/g' file > outfile(演示)
  • - grep -Eo '[Ff][Oo][Oo]|BAR' file(或者如果您使用 GNU grep,您仍然可以使用 PCRE 正则表达式,grep -Po '(?i:foo)|BAR' file演示))
于 2019-11-12T11:51:44.327 回答
6

您使用什么语言?执行此操作的标准方法是 /([Ff][Oo]{2}|BAR)/ 启用区分大小写,但在 Java 中,例如,有一个区分大小写的修饰符 (?i) 使所有它右边的字符不区分大小写和 (?-i) 强制敏感。可以在此处找到该 Java 正则表达式修饰符的示例。

于 2008-09-04T12:41:19.857 回答
6

不幸的是,不区分大小写的匹配语法并不常见。在 .NET 中,您可以使用 RegexOptions.IgnoreCase 标志或?i修饰符

于 2008-09-04T12:41:45.083 回答
4

你可以使用

(?:F|f)(?:O|o)(?:O|o)

.Net 括号中的 ?: 表示它是非捕获的,仅用于对 | 的术语进行分组。(或)声明。

于 2008-09-04T12:37:31.473 回答