如何使用Unicode名称在Java中查找字符或int代码点?
例如,如果
Character.getName('\u00e4')返回"LATIN SMALL LETTER A WITH DIAERESIS",如何使用“普通”Java执行反向操作(即从"LATIN SMALL LETTER A WITH DIAERESIS"到'\u00e4')?
编辑:为了停止我想要或不想要的评论的洪流,下面是我在中应该做的事情:
"\N{LATIN SMALL LETTER A WITH DIAERESIS}" # this gives me what I want as a literal
unicodedata.lookup("LATIN SMALL LETTER A WITH DIAERESIS") # a dynamic version现在,问题是:在Java中做同样的事情。
而且,BTW,我不想“打印unicode转义符”--实际上,字符的十六进制很容易得到,但是我想要一个带有名字的字符。
,换句话说,,我想做Character.getName(int)所做的相反的事情。
发布于 2019-08-18 05:12:15
对于JDK 9和更高版本,使用静态方法Character.codePointOf(String name)是最简单的方法:
公共静态int代码点(字符串名) 返回由给定Unicode字符名指定的Unicode字符的代码点值。
这适用于所有的Uniocde字符,而不仅仅是那些基本的多语言平面上的字符。例如,在Java 12上运行此代码.
String s1 = "LATIN SMALL LETTER A WITH DIAERESIS";
int cp1 = Character.codePointOf(s1);
System.out.println("Unicode name \"" + Character.getName(cp1) + "\" => code point " + cp1 + " => character " + Character.toString(cp1));
String s2 = "EYES";
int cp2 = Character.codePointOf(s2);
System.out.println("Unicode name \"" + Character.getName(cp2) + "\" => code point " + cp2 + " => character " + Character.toString(cp2));
String s3 = "DNA Double Helix"; // Only works with JDK12 and later. Otherwise java.lang.IllegalArgumentException is thrown.
int cp3 = Character.codePointOf(s3);
System.out.println("Unicode name \"" + Character.getName(cp3) + "\" => code point " + cp3 + " => character " + Character.toString(cp3));...produces输出..。
Unicode name "LATIN SMALL LETTER A WITH DIAERESIS" => code point 228 => character ä
Unicode name "EYES" => code point 128064 => character
Unicode name "DNA DOUBLE HELIX" => code point 129516 => character 总结一下这些转变:
Character.getName(codepoint)Character.toString(codepoint)Character.codePointOf(name)Character.toString(Character.codePointOf("LATIN SMALL LETTER A WITH DIAERESIS"));。备注:
Character.codePointOf("DNA Double Helix")时将得到一个IllegalArgumentException。发布于 2014-05-15 08:03:07
ICU4J库可以在这里帮助您。它有一个带有UCharacter和其他相关方法的类,这些方法可以从各种类型的字符名字符串映射回它们表示的int代码点。
但是,如果您正在使用硬编码字符名(即源代码中引用的字符串文字),那么一次转换(在源代码中使用\u转义并在必要时添加带有全名的注释)将更加有效,而不是每次运行时都需要解析名称表的成本。如果字符名来自读取文件或类似的文件,那么显然您必须在运行时进行转换。
发布于 2018-11-11 22:31:51
我希望这个仅依赖于“普通”Java的类将对某些人有用。它利用了延迟填充的查找表,这些查找表可以通过reset(false)调用随时清除,以释放内存(如果需要,可以自动填充表并再次使用它)。如果要查找的字符位于较低的Unicode块(通常是这样),则此表的填充时间几乎不明显。我添加了可选的可能性,通过调用reset(true)预先填充整个表。
还请注意,在Unicode名称冲突和U+0007之间有已知的U+1F514。Java的Character.getName()仍然返回前者的“贝尔”。所呈现的类试图至少在反向操作中修复这个问题,返回分配给它的已批准的唯一名称“警报”的U+0007。
import java.util.Map;
import java.util.HashMap;
public class UnicodeTable {
public static final char INVALID_CHAR = '\uFFFF';
private static final Map<String, Integer> charMap = new HashMap<>();
private static boolean incomplete;
private static int lastLookup;
static {
reset(false);
}
public static int getCodePoint(String name) {
Integer cp = charMap.get(name);
if (cp == null && incomplete) {
while (++lastLookup <= Character.MAX_CODE_POINT) {
String uName = Character.getName(lastLookup);
if (uName != null) {
charMap.put(uName, lastLookup);
if (uName.equals(name))
return lastLookup;
}
}
incomplete = false;
}
return cp == null ? INVALID_CHAR : cp;
}
public static char getChar(String name) {
int cp = getCodePoint(name);
return Character.isBmpCodePoint(cp) ? (char)cp : INVALID_CHAR;
}
private static final int ALERT = 0x000007;
private static final int BELL = 0x01F514;
public static void reset(boolean fillUp) {
if (!fillUp) {
charMap.clear();
incomplete = true;
lastLookup = Character.MIN_CODE_POINT - 1;
charMap.put("ALERT", ALERT);
String bName = Character.getName(BELL);
if (bName.equals(Character.getName(ALERT))) {
getCodePoint(bName);
charMap.put(bName, BELL);
}
} else if (incomplete) {
while (++lastLookup <= Character.MAX_CODE_POINT) {
String uName = Character.getName(lastLookup);
if (uName != null)
charMap.put(uName, lastLookup);
}
incomplete = false;
}
}
}https://stackoverflow.com/questions/23671346
复制相似问题