在Java正则表达式中匹配Unicode破折号?

7

我正在尝试使用Pattern.split()方法,编写一个Java正则表达式将一般格式为“foo - bar”的字符串拆分成“foo”和“bar”。这里的“-”字符可能是多个破折号中的一个:ASCII破折号、em-dash、en-dash等。我构建了以下正则表达式:

private static final Pattern titleSegmentSeparator = Pattern.compile("\\s(\\x45|\\u8211|\\u8212|\\u8213|\\u8214)\\s");

如果我正确地阅读了Pattern文档,这个模式应该可以捕获任何unicode破折号或ascii破折号,只要两边都有空格。我使用的模式如下:

String[] sectionSegments = titleSegmentSeparator.split(sectionTitle);

没有成功。对于下面的示例输入,破折号未被检测到,而titleSegmentSeparator.matcher(sectionTitle).find()返回false!为了确保我没有错过任何不寻常的字符实体,我使用System.out打印了一些调试信息。输出如下--每个字符后面都跟着(int)char的输出,这应该是它的Unicode代码点,不是吗?样例输入:看起来像那个破折号是代码点8211,应该与正则表达式匹配,但它没有!这里发生了什么?

从文档中: "字符串"\ u2014"和"\ u2014",虽然不相等,但编译成相同的模式,该模式匹配十六进制值为0x2014的字符。也就是说,您可以在表达式中删除双\。 - aioobe
@aioobe:Java文档恰好使用了这个问题所涉及的一个字符作为示例,这真是一个巨大的巧合。或者你修改了引用吗? - Tim Pietzcker
1个回答

13

你混淆了十进制数(8211)和十六进制数(0x8211)。

\x\u 都需要一个十六进制数字,因此要匹配破折号,你需要使用\u2014,而不是\u8211(对于普通连字符等,则使用\x2D)。

但为什么不直接使用 Unicode 属性“Dash punctuation”呢?

作为Java字符串: "\\s\\p{Pd}\\s"


哎呀,Java在其正则表达式中不支持Unicode的“Dash”属性,其中包括MINUS SIGN这样的Symbol类型。 - tchrist

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