比较两个在字典级别上按词典相同但不相同的字符串

Dav*_*avz 10 java string utf-8

我正在寻找一种方法来比较两个字典级别的词典等效但不相同的Java字符串.

更准确地说,使用以下文件名"baaaé.png",在字节级别它可以用两种不同的方式表示:

[ 98,97,97,97,-61,-87,46,112,110,103 ] - >"é"用2个字节编码

[ 98,97,97,97,101,-52,-127,46,112,110,103 ] - >"é"用3个字节编码

    byte[] ch = {98, 97, 97, 97, -61, -87, 46, 112, 110, 103};
    byte[] ff = {98, 97, 97, 97, 101, -52, -127, 46, 112, 110, 103};

    String st = new String(ch,"UTF-8");
    String st2 = new String(ff,"UTF-8");
    System.out.println(st);
    System.out.println(st2);
    System.out.println(st.equals(st2));
Run Code Online (Sandbox Code Playgroud)

将生成以下输出:

baaaé.png
baaae?.png
false
Run Code Online (Sandbox Code Playgroud)

有没有办法进行比较,以便equals方法返回true?

Pet*_*ott 8

您可以使用具有适用强度的Collat​​or类来规范化不同重音符号等内容.这将允许您成功地比较字符串.

在这种情况下,US语言环境和TERTIARY强度足以使字符串相等

Collator usCollator = Collator.getInstance();
usCollator.setStrength(Collator.TERTIARY);
System.out.println(usCollator.equals(st, st2));
Run Code Online (Sandbox Code Playgroud)

输出

true
Run Code Online (Sandbox Code Playgroud)

您还可以使用Java的Normalizer类在不同形式的Unicode之间进行转换.这将转换您的字符串,但它们最终会相同,允许您使用标准字符串工具进行比较

最后,我们可能想看一下ICU(Unicode的国际组件)项目,它提供了许多工具,可以用很多不同的方式处理Unicode字符串.


Cel*_*ada 7

您需要查看两种Unicode规范化表单:

首先是NFC与NFD.您在问题中提供的示例是NFC和NFD之间不同的一个很好的例子.你的第一个字符串是NFC,而你的第二个字符串是NFD.

在Unicode中,许多重音字符可以用两种不同的方式表示:作为基本字符后跟组合重音,或作为预组合的重音字符.NFC在可用区域时使用预先组合的字符.NFD总是使用分解形式.

通常我们不使用NFC和NFD的混合物.大多数环境指定哪个是首选形式.非常简单:MacOS X文件名使用NFD,其他几乎所有使用NFC.但是如果给你的输入可能是"其他"规范化形式,你可以轻松转换它:过程很简单(使用Unicode字符数据库提供的信息)和无损(即你可以在NFC之间来回切换)和NFD,如果你希望不丢失信息).

java提供了一个名为Normalizer的内置类,它可以将字符串转换为给定的Unicode形式.

还有2种其他标准化形式:NFKC和NFKD.这些表格不适用于一般用途,但仅用于词典比较.例如,在搜索或比较中,¼应被认为与1/4相同.但它们并不意味着¼和1/4是相同的,或者一般应该转换成另一个.

从NFC到NFKC以及从NFD到NFKD的转换再次简单(你需要角色数据库),但这次它是有损的.您需要保留原始的NFC/NFD文本,并仅将NFKC/NFKD用作搜索/排序键.