Java 带有Unicode的正则表达式模式不';不要折叠箱子
在C#中,似乎在大多数情况下,Java 带有Unicode的正则表达式模式不';不要折叠箱子,java,regex,internationalization,case-folding,Java,Regex,Internationalization,Case Folding,在C#中,似乎在大多数情况下,Grüsse和Grüße被认为是平等的,正如nice网页所解释的那样。我试图在Java中找到类似的行为-显然不是在Java.lang.String中 我认为我很幸运地将java.regex.Pattern与Pattern.UNICODE\u CASE结合在一起。Javadoc说: UNICODE大小写支持UNICODE大小写折叠。当指定此标志时,则 不区分大小写匹配,当由不区分大小写标志启用时, 以符合Unicode标准的方式完成 然而,以下代码: Pattern
Grüsse
和Grüße
被认为是平等的,正如nice网页所解释的那样。我试图在Java中找到类似的行为-显然不是在Java.lang.String
中
我认为我很幸运地将java.regex.Pattern
与Pattern.UNICODE\u CASE
结合在一起。Javadoc说:
UNICODE大小写支持UNICODE大小写折叠。当指定此标志时,则
不区分大小写匹配,当由不区分大小写标志启用时,
以符合Unicode标准的方式完成
然而,以下代码:
Pattern p = Pattern.compile(Pattern.quote("Grüsse"),
Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
System.out.println(p.matcher("Grüße").matches());
产生false
。为什么?有没有其他方法可以复制C#case折叠行为
----编辑--
正如@VGR指出的,String.toUpperCase
将ß
转换为ss
,这可能是也可能不是大小写折叠(可能我在这里混淆了概念)。但是,德语地区的其他字符没有“折叠”,例如u
不会变成UE
。因此,为了使我的初始示例更加完整,是否有一种方法可以使Grüße
和Gruesse
在Java中比较相等
我认为可以使用
java.text.Normalizer
类来实现这一点,但它将u
转换为u?
而不是ue
。它也没有提供区域设置的选项,这让我更加困惑。使用ICU4J正则表达式,而不是JDK正则表达式:
以下事实仅供参考:
Character.toUpperCase()
无法将大小写折叠为一个字符
必须映射到一个字符
String.toUpperCase()
将进行大小写折叠
String.equalsIgnoreCase()
使用字符.toUpperCase()
内部,所以不做案件折叠
结论(正如@VGR指出的):如果您需要大小写不敏感的匹配和大小写折叠,您需要做:
foo.toUpperCase().equals(bar.toUpperCase())
而不是:
foo.equalsIgnoreCase(bar)
至于u
和ue
相等,我已经设法用rulebasedcolator
和我自己的规则来实现了这一点(人们会期望Locale.German
内置了这一点,但遗憾的是)。它看起来非常愚蠢/设计过度,因为我只需要相等,而不需要排序/排序,最后我决定在比较之前使用一组简单的String.replace
。它很差劲,但它可以工作,而且是透明的/可读的。原因:javadoc还说:“这个类符合的是级别1,再加上RL2.1规范等价物。”-链接的doc声明“在级别1,只需要简单的大小写匹配”-可能无法与实际的java SE实现一起工作…我非常确定s1.toUpperCase().equals(s2.toUpperCase())
将起作用。equalsIgnoreCase将不起作用,因为正如其文档所述,它一次只执行一个字符的大小写转换,因此只应用一对一字符的映射。感谢两位富有洞察力的评论。@VGR您是对的,这是有效的。但我提出了另一个问题-请参见编辑。“SS”
等于“ß”.toUppercase(Locale.derman)”
但这并不适用于“ss.equals”(“ß”)
.A,它的强度设置为将实现您最初的目标。但我不确定是否可以将“Grüße”和“Gruesse”等同起来。