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

Do Java regular expressions support collating sequences?

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

[[.ch.]]*c matches the first to fifth character in the string chchch

当我在 Java 中测试它时,它确实匹配那些字符,但 [[ch]]*c 也是如此。因此,我不确定整理符号是否得到尊重。是吗?

TL;DR - 编号


你reading/quoting的规格是Open Group的SUS (Single UNIX® Sspecification) IEEE POSIX (Portable Operating [=98=正则表达式部分的版本]S系统IuniX)标准集合的接口。 (参见 https://www.regular-expressions.info/posix.html ¹)

一般来说,只有 POSIX 兼容的正则表达式引擎完全支持 POSIX bracket expressions,这本质上就是其他正则表达式风格所称的字符 classes,但有一些特殊功能,一个当在表达式中使用时,[..] 被解释为整理序列的开始和结束。

不幸的是,很少有正则表达式引擎是 POSIX 兼容的,事实上,一些声称实现 POSIX 正则表达式的引擎只是使用 POSIX 定义的正则表达式语法,而不是没有完整的 locale 支持。因此他们没有实现括号表达式 features/quirks.

的 all/any

Java 的正则表达式绝不是 POSIX 兼容的,从这个 Regular Expression Engine Comparison Chart 可以看出 ²。它的 regex 包实现了一个 "Perl-like" 正则表达式引擎,缺少一些功能(例如条件表达式和注释),但包括一些额外的功能(例如所有格量词和可变长度,但有限的后视断言).

Perl 和 Java 都不支持排序相关的括号分隔符 [==](字符等价),或 [..](排序顺序)。 Perl 确实支持使用 POSIX [::] 分隔符的字符 classes,但是 Java 仅支持使用 \p 运算符(带有正如所解释的一些注意事项 here).


那么,Java 中的正则表达式 [[.ch.]]*c 是怎么回事? (我忽略了捕获组,因为它不会改变分析。)

嗯,事实证明 Java 的 regex 包在其字符 classes 中支持 unions。这是通过嵌套实现的。例如,[<em>set1</em>[<em>set2</em>]] 等同于 [<em>set3</em>] 其中<em>set3</em>中的字符是[=109中字符的并集=]set1<em>set2</em>中的字符。 (顺便说一句,请注意 [[<em>set1</em>][<em>set2</em>]][[<em>set1</em>]<em>set2</em>] 也产生相同的结果。)

所以,[[.ch.]] 只是字符 class 包含空字符集与字符 class [.ch.] 中的字符集的并集,所以基本上和class[.ch.]这个字符是一样的。这等同于 [.ch](因为第二个 . 是多余的)因此 [[.ch.]]*c[.ch]*c.

相同

同样,[[ch]]*c 简化为 [ch]*c

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


备注:

这不是演示整理序列或检测它们是否已实现的很好示例,因为 [[.ch.]]*c 将在支持整理序列时匹配 chchch 中的 chchc (并且 ch 是当前语言环境中的有效序列)并且当它们不是但联合是时。

更好的 demo/test 是使用正则表达式 [[.ch.]] 和测试字符串 ch:

  • 如果 ch 匹配,则支持整理序列。
  • 任何其他匹配都表示它们不是。
  • 如果返回错误,它们 可能 得到支持,因为如果 ch 在当前语言环境中不是有效序列(它是一个有效的整理捷克语言环境中的顺序):
    • 如果错误指定 ch 不是有效的整理顺序,则 受支持。
    • 如果返回的错误是 delimiter/token [. and/or .] 是 invalid/unsupported,则整理序列 不是 支持。
    • 如果错误不明确,或者为了确保检查支持的方式,您需要切换到捷克语言环境(并确认 ch 确实是一个有效的整理顺序)或切换到任何其他语言环境具有至少一个定义的整理顺序的语言环境,可以用来代替 ch.

¹ 我既不是 Jan Goyvaerts,也不隶属于 Regular-Expressions.info 网站。
² 我也不是CMCDragonkai.