Java正则表达式是否支持整理序列?

时间:2018-10-11 03:18:30

标签: java regex collation

我正在针对测试字符串([[.ch.]]*)c尝试使用正则表达式chchch。根据{{​​3}}:

  

[[。ch。]] * c与字符串chchch中的第一个到第五个字符匹配

当我在Java中进行测试时,它确实与那些字符匹配,但是[[ch]]*c也是如此。因此,我不确定是否要使用归类符号。是吗?

1 个答案:

答案 0 :(得分:2)

TL; DR-否


您正在阅读/引用的规范是Open Group的正则表达式的SUS( S 单个 U NIX® S IEEE POSIX的一部分( P 可稳定的 O 对uni X 执行 S 系统 I >)标准的收集。 (请参见https://www.regular-expressions.info/posix.html¹)

通常,只有符合POSIX的正则表达式引擎完全支持POSIX bracket expressions,这实际上是其他正则表达式风格所称的字符类,但是具有一些特殊功能,其中一个是[.和{{1 }}在表达式中使用时,被解释为整理序列的开始和结束。

不幸的是,很少有符合POSIX的正则表达式引擎,实际上,一些声称实现POSIX正则表达式的引擎仅使用POSIX定义的正则表达式语法,而没有完整的locale支持。因此,他们没有实现所有/任何括号表达功能/怪癖。

Java的正则表达式与POSIX都不兼容,如Regular Expression Engine Comparison Chart所示。它的.]包实现了一个“ Perl样”的正则表达式引擎,缺少一些功能(例如条件表达式和注释),但是包括一些额外的功能(例如所有格修饰符和可变长度但有限的后置断言) )。

Perl和Java都不支持与归类相关的括号定界符regex[=(等价字符),或=][.(归类序列)。 Perl确实使用POSIX .][:分隔符来支持字符类,但是Java仅使用:]运算符来支持字符类(有一些警告,如here所述)。


那么,Java中的正则表达式\p怎么了? (我忽略了捕获组,因为它不会更改分析。)

好吧,事实证明Java的[[.ch.]]*c包在其字符类中支持unions。这是通过嵌套实现的。例如,regex等效于[set1[set2]],其中[set3]中的字符是set3中的字符和set1中的字符的并集。 (顺便提一下,set2[[set1][set2]]也会产生相同的结果。)

因此,[[set1]set2]只是字符类,包含空字符集与字符类[[.ch.]]中的字符集的并集,因此基本上与字符类{{ 1}}。这等效于[.ch.](因为第二个[.ch.]是多余的),因此[.ch].相同。

类似地,[[.ch.]]*c简化为[.ch]*c

最后,由于字符串[[ch]]*c中没有[ch]*c个字符,因此正则表达式.chchch会产生相同的结果。 (尝试对字符串[.ch]*c进行测试,以查看区别并证明上述内容。)


注释:

这不是一个演示整理序列或检测它们是否已实现的很好的例子,因为在支持整理序列的情况下,[ch]*c将与c.hchch中的[[.ch.]]*c相匹配(并且chchc是当前语言环境中的有效序列),如果不是,则是联合。

更好的演示/测试是使用正则表达式chchch和测试字符串ch

  • 如果[[.ch.]]被匹配,则支持排序顺序。
  • 其他任何比赛都不是。
  • 如果返回错误,可能会 被支持,因为如果ch在当前语言环境中不是有效序列(在捷克语言环境中是有效的整理序列),则会发生这种情况):
    • 如果错误表明ch不是有效的整理序列,则 受支持。
    • 如果返回的错误是分隔符/令牌ch和/或ch无效/不受支持,则整理序列不支持
    • 如果错误是模棱两可的,或者是一种确定的支持检查方式,则需要切换到捷克语言环境(并确认[.确实是有效的整理顺序)或切换到该语言环境至少有一个已定义的整理序列,可以代替.]使用。

¹我既不是Jan Goyvaerts,也不是Regular-Expressions.info网站的任何会员。
²我不是CMCDragonkai。