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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用正则表达式剥离字符失败,使用带有变音符号,撇号,重音符号等的文字字符相关的知识,希望对你有一定的参考价值。

我正在尝试生成符合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而不是文字à。原因是,à字符可以用两种方式编码:

  • à字符作为单个代码点(文字à)
  • à字符作为双重代码点(后跟重音符号)

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

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

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

以上是关于使用正则表达式剥离字符失败,使用带有变音符号,撇号,重音符号等的文字字符的主要内容,如果未能解决你的问题,请参考以下文章

局部匹配忽略案例和变音符号

带有德语变音符号的 JSON Jackson + HTTPClient

Ruby 超级不敏感的正则表达式将学校名称与口音和其他变音符号匹配

正则表达式用破折号、空格破折号、点空间、点和带有空字符串的撇号替换空格

带有变音符号的 Unicode 字符串,按字符分割

带有德语变音符号的 iOS 上的 FacebookDisplayName