在Java中如何匹配Unicode字符

9

我正在尝试在Java中匹配Unicode字符。

输入字符串:informa

要匹配的字符串:informátion

目前我尝试了以下方法:

Pattern p= Pattern.compile("informa[\u0000-\uffff].*", (Pattern.UNICODE_CASE|Pattern.CANON_EQ|Pattern.CASE_INSENSITIVE));
    String s = "informátion";
    Matcher m = p.matcher(s);
    if(m.matches()){
        System.out.println("Match!");
    }else{
        System.out.println("No match");
    }

它的翻译是“没有匹配项”。有什么想法吗?

2
îñfórmåtìön怎么样?应该匹配吗? - kennytm
是的,那就是想法。现在只需要á就可以了。 - ankimal
3个回答

13
术语“Unicode字符”不够具体。它将匹配Unicode范围内的每个字符,因此也包括“普通”字符。然而,当人们实际上指的是“不在可打印ASCII范围内的字符”时,这个术语经常被使用。
在正则表达式中,这将是[^\x20-\x7E]
boolean containsNonPrintableASCIIChars = string.matches(".*[^\\x20-\\x7E].*");

根据您想要使用这些信息的目的,以下是一些有用的后续答案:


java.text.Normalizer似乎是正确的选择(第二点)。Unicode匹配似乎无法按预期工作,即使它能够正常工作,我也可能会受到性能惩罚。 - ankimal
如果您的实际功能要求是“去除变音符号”,那么这确实是正确的方法。您最初的问题只是没有像这样明确表述 :) - BalusC
我认为问题并不十分清晰。目标是能够将“information”与“informátion”匹配,因此需要能够将'a'与任何形式的'a'(如'á'、'å'等)进行匹配。去除变音符号然后进行匹配似乎是可行的方法。 - ankimal

7

是因为informa根本不是informátion的子字符串吗?

如果在您的正则表达式中删除了informa中的最后一个a,您的代码会如何运行?


informa\u0301在模式字符串中起作用。这与Pattern.CANON_EQ案例有关。 - ankimal
忘记放入此链接:http://java.sun.com/docs/books/tutorial/essential/regex/pattern.html(Pattern.CANON_EQ) - ankimal

2

看起来你想在匹配字母时忽略变音符号。如果是这样,那么将你的字符串规范化为NFD形式,去除变音符号,然后进行搜索。

String normalized = java.text.Normalizer.normalize(textToSearch, java.text.Normalizer.Form.NFD);
String withoutDiacritical = normalized.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
// Search code goes here...

了解有关NFD的更多信息:


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