假设Unicode和不区分大小写,模式“..”是否匹配“FfIsS”?

时间:2013-10-02 10:57:20

标签: java regex unicode case-insensitive case-folding

这听起来像个笑话,但我可以证明这一点。

假设:

  • Dot匹配任何单个字符。
  • 当且仅当匹配s时,不区分大小写的模式与s.toUpperCase()匹配。

以下所有内容都非常合乎逻辑,并且在Java中保留:

  • "ffi".matches(".") LATIN SMALL LIGATURE FFI(U + FB03)是一个角色,所以它必须匹配
  • "ß".matches(".") LATIN SMALL LETTER SHARP S(U + 00DF)是一个角色,所以它必须匹配
  • Unicode标准
  • "ffi".toUpperCase().equals("FFI")(没有资本连字FFI)
  • 通过Unicode标准
  • "ß".toUpperCase().equals("SS")(有一个大写的S,但它没有被使用)
  • "FfI".toUpperCase().equals("FFI")显然
  • "sS".toUpperCase.equals("SS")显然

假设正则表达式中的第一个点代表而第二个代表ß,则正则表达式必须匹配“FFISS”,并且因为不区分大小写也是“FfIsS”。

确实希望有什么不对劲,否则正则表达式会变得非常不可用。

问题:

  • 我的“证据”有什么问题?
  • 如果我的第二个假设不成立,那么“不区分大小写”究竟意味着什么?

1 个答案:

答案 0 :(得分:1)

正如maaartinus在他的评论中所指出的,Java提供(至少在理论上)Unicode支持不区分大小写的reg-exp匹配。 Java API文档中的措辞是“以与Unicode标准一致的方式”进行匹配。但问题是,Unicode标准为案例转换和不区分大小写的匹配定义了不同级别的支持,API文档未指定 Java语言支持哪个级别。

虽然没有记录,但至少在Oracle的Java VM中,reg-exp实现仅限于所谓的简单不区分大小写的匹配。与示例数据相关的限制因素是,如果案例折叠(转换)导致相同数量的字符并且集合(例如“。”)仅限于输入中的一个字符,则匹配算法仅按预期工作串。第一个限制甚至导致“ß”与“SS”不匹配,正如您可能已经预料到的那样。

要获得对字符串文字之间完全不区分大小写匹配的支持,可以使用ICU4J library中的reg-exp实现,以便至少“ß”和“SS”匹配。但是,AFAIK没有针对Java的reg-exp实现,完全支持组,集和外卡。