用Java将UTF-8转换为ASCII

时间:2018-11-27 13:55:26

标签: java utf-8

我有一个包含UTF-8字符集格式的字符串。

String str = "100µF";

我上面的字符串的期望输出是“ 100µF”

我检查了StackOverflow,并得到了下面的代码

public static String decompose(String s) {
    return java.text.Normalizer.normalize(s, java.text.Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+","");
}

但是,我得到上面的字符串的输出是“ 100AµF”

3 个答案:

答案 0 :(得分:2)

这是XY problem

这里的问题是您的字符串是使用不正确的字符集从字节创建的,该字符集假定一个字节是一个字符,例如ISO 8559-1

但是字节不是ASCII,也不是ISO 8859-1。字节是文本的UTF-8表示形式。

请勿替换任何字符。不要规范化字符串。唯一的 correct 解决方案是将错误解码的String还原为字节,然后使用UTF-8正确解码字节:

byte[] originalBytes = str.getBytes(StandardCharsetes.ISO_8859_1);

str = new String(originalBytes, StandardCharsets.UTF_8);

答案 1 :(得分:1)

ASCII中没有µ字符,因此您不能以ASCII形式编写。

Java String 是Unicode字符序列(并且在内部以UTF-16编码),因此您遇到的问题取决于读取此字符串的方式或写入方式。 / p>

通常,这可以通过创建设置正确字符集的OutputStreamWriter(OutputStream out, String charsetName)InputStreamReader(InputStream in, String charsetName)来解决。

因此,例如,如果您是从UTF-8编码文件中获取字符串的,则应创建一个类似这样的阅读器:

Reader in = new InputStreamReader(new FileInputStream('some_file.txt'),"UTF-8")

或者,如果要写入ISO-Latin-1文件,则应按以下方式创建Writer:

Writer out = new OutputStreamWriter(new FileOutputStream('some_file.txt'),"ISO-8859-1")

HTTP请求/响应可能会发生类似的情况,具体取决于应用服务器或浏览器对每个请求的主体的解释方式,如果是这种情况,则可以在问题中添加一些细节。

答案 2 :(得分:0)

您正在处理µ(U + 00B5,MICRO SIGN)和Â(U + 00C2,带大写字母的拉丁大写字母A)。这两个字符都属于Latin-1 Supplement unicode block

如果您想允许µ但不允许Â,则必须自己进行过滤。每个字符都不会有单独的字符组(\p{})。

一种方法是定义白名单过滤器:

String input = "100µF";
String allowedFilter = "[^\\p{ASCII}µ]"; // regular ASCII + µ sign
String output = input.replaceAll(allowedFilter, "");
System.out.println(output); // 100µF

请注意,µÂ都可以用Extended ASCII表示,因此过滤一个而不过滤另一个是很不直观的。