如何检测 Java 字符串中的 unicode 字符?

Posted

技术标签:

【中文标题】如何检测 Java 字符串中的 unicode 字符?【英文标题】:How do I detect unicode characters in a Java string? 【发布时间】:2010-12-13 00:18:02 【问题描述】:

假设我有一个包含 Ü 的字符串。我将如何找到所有这些 un​​icode 字符?我应该测试他们的代码吗?我该怎么做?

例如,给定字符串“AÜXÜ”,我想将其转换为“AYXY”。我想对其他 unicode 字符做同样的事情,我不想将它们存储在某种翻译映射中。

【问题讨论】:

如果没有自己的地图,你怎么知道 Ü 会映射到什么?没有简单的映射,我怀疑在不同的语言中,任何映射都可能不同 其实你可以通过逐个查看字符来做到这一点。这取决于 char 的“范围”,但它的级别很低,我认为已经有一些东西可以完成这项任务。见en.wikipedia.org/wiki/Unicode 也可以在这里查看解决方案:rosettacode.org/wiki/… 【参考方案1】:

你可以遍历你的字符串和每个字符调用

If (Character.UnicodeBlock.of(c) != Character.UnicodeBlock.BASIC_LATIN) 
 // replace with Y

【讨论】:

测试代码点的好人,但我不认为他想用 Y 替换 every 字符。 好吧,他说 unicode 字符,我知道他可能是指用 Y 替换所有非 ascii 字符。随便【参考方案2】:

“unicode 字符”的定义含糊不清,但将被视为标准 ISO 8859 charset 未涵盖的 UTF-8 字符。如果在您的情况下是这样,则遍历字符串中的所有字符并测试其代码点以确定它是否在给定字符集中。

或者,使用Map<Character, Character> 和映射中包含匹配键的字符。例如:

Map<Character, Character> charReplacementMap = new HashMap<Character, Character>() 
    put('Ü', 'Y');
    // Put more here.
;

String originalString = "AÜAÜ";
StringBuilder builder = new StringBuilder();

for (char currentChar : originalString.toCharArray()) 
    Character replacementChar = charReplacementMap.get(currentChar);
    builder.append(replacementChar != null ? replacementChar : currentChar);


String newString = builder.toString();

或者,您的意思是“所有带有变音符号的字符”?如果是这样,则使用java.text.Normalizer 删除变音符号:

/**
 * Remove any diacritical marks (accents like ç, ñ, é, etc) from
 * the given string (so that it returns plain c, n, e, etc).
 * @param string The string to remove diacritical marks from.
 * @return The string with removed diacritical marks, if any.
 */
public static String removeDiacriticalMarks(String string) 
    return Normalizer.normalize(string, Form.NFD)
        .replaceAll("\\pInCombiningDiacriticalMarks+", "");

有一个陷阱,Ü 会变成 U,而不是 Y。不确定这是否是您所追求的。如果你想用发音字符替换,你真的需要创建一个映射。当然,这是一项乏味的工作,但完成的时间比您学习本主题所需的时间要短。

【讨论】:

我通常是这样做的。但这需要您在地图中添加每个角色。 我没有看到任何其他有效的选项可以将某个字符替换为某个字符以及多个字符。 如果不将每个字符添加到地图中,如何定义替换?还是您希望将所有非 ascii 字符替换为单个 ascii 字符? @BalusC - 实际上,Unicode 字符(代码点)的真正定义非常精确。问题是 OP 不理解 ASCII 字符是 Unicode 代码点的正确子集。 或者您只是想删除变音符号?我已经用它编辑了我的帖子。【参考方案3】:

您可以反过来询问该字符是否为 ascii 字符。

public static boolean isAscii(char ch) 
    return ch < 128;

当然,你必须逐个字符地分析字符串。

(该方法来自commons-lang CharUtils,其中包含大量有用的字符方法)

【讨论】:

【参考方案4】:

我不清楚将“AÜXÜ”转换为“AYXY”到底能得到什么。这是因为 Ü 在特定语言中的发音像 Y 吗?什么语言?还有哪些其他规则可能适用?


就术语而言...

"a"

上面是一个Unicode字符串。它包含一个 UTF-16 编码字符。

如果您希望将字符范围限制为英文字母,请查看Normalization performed in this answer。

【讨论】:

这只是一个替代示例。我实际上会用_XX_ 替换字符:)【参考方案5】:

从您的示例中我不确定您要做什么 - 如果您只是想用 Y 替换所有非 ASCII 值,那么您可以遍历字符串以查找范围 0 之外的代码点到 127,然后用 Y 替换那些代码点。

【讨论】:

【参考方案6】:

Character 类也提供了一些有趣的方法。看看吧。

Character.UnicodeBlock.of('a') == Character.UnicodeBlock.BASIC_LATIN; //true

Character.UnicodeBlock.of('�') == Character.UnicodeBlock.BASIC_LATIN; //false

【讨论】:

以上是关于如何检测 Java 字符串中的 unicode 字符?的主要内容,如果未能解决你的问题,请参考以下文章

java如何把以unicode编码形式的字符串变成编码前的形式

Java中的字节流和字符流区别

Java中的字节流和字符流区别

如何判断一个字符串是不是是unicode编码?

Java IO浅析

Java IO 要点总结