使用带有变音符号、撇号、重音符号等的文字字符使用正则表达式剥离字符失败

Stripping characters using a regex fails using literal characters with diacritics, apostrophes, accents, and the like

我正在尝试生成符合 XSD 中模式的字符串。要去除未出现在 XSD 模式中的任何字符,我正在执行以下操作(replaceAll 调用从我的代码中逐字复制):

import java.lang.String;

public class HelloWorld {
    public static void main(String[] args) {
        test("Führ");
    }

    private static void test( String name ) {
        name = name.toUpperCase( );
        name = name.replaceAll (
            "[^A-ZА-ЯΑ-ΩÄÀÁÂÃÅǍĄĂÆÇĆĈČĎĐÐÈÉÊËĚĘĜĢĞĤÌÍÎÏĴĶĹĻŁĽÑŃŇÖÒÓÔÕŐØŒŔŘẞŚŜŞŠȘŤŢÞȚÜÙÚÛŰŨŲŮŴÝŸŶŹŽŻ, '\-–]", 
            ""
        );
        System.out.println(name);
    }
}

该片段运行良好,并打印出 "FÜHR"。但是,在我使用 运行 的环境中,使用完全相同的 replaceAll 语句, replaceAll 调用删除 Ü 字符并打印出 FHR数据(即名称)来自数据库,并以与代码片段 ("Führ") 中相同的字符开头。

我很困惑...可能是什么原因,我该如何解决?


PS: 源文件的编码为UTF-8 (Eclipse .settings: encoding//<<<src-path>>>.java=UTF-8)

显然,当匹配带有变音符号、撇号、重音符号等的字符时,应该使用 unicode 单代码点指定字符。

例如,对于 à 字符,正则表达式应指定 \u00E0 而不是文字 à。原因是,à 字符可以用两种方式编码:

  • 作为单码位的 à 字符(文字 à)
  • 作为双代码点的 à 字符(a 后跟重音符 `)

在正则表达式中指定 unicode 代码点 \u00E0 将匹配 à 的两种编码。在正则表达式中指定文字 à 将仅匹配该字符在您的代码片段中的编码方式,如果它被编码为双代码点,它将不匹配单代码点版本相同的字符。

使用 unicode 单代码点重写正则表达式解决了问题。对于问题中的 Ü 字符,正则表达式应指定 \u00DC。这匹配 Ü.

的单代码点和双代码点编码。

我在这里找到了导致解决方案的信息:Regex Tutorial - Unicode Characters and Properties(段落:匹配特定代码点)。