Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中UTF-8到ASCII的转换_Java_Utf 8 - Fatal编程技术网

java中UTF-8到ASCII的转换

java中UTF-8到ASCII的转换,java,utf-8,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{InCombiningDiacritica

我有一个字符串包含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”

ASCII中没有
µ
字符,所以不能用ASCII编写

Java字符串是unicode字符序列(内部编码为UTF-16),因此您遇到的问题取决于如何读取该字符串或如何编写该字符串

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

因此,例如,如果您从UTF-8编码的文件中获取字符串,则应创建如下读取器:

Reader in = new InputStreamReader(new FileInputStream('some_file.txt'),"UTF-8")
Writer out = new OutputStreamWriter(new FileOutputStream('some_file.txt'),"ISO-8859-1")
或者,如果要写入ISO-Latin-1文件,则应按以下方式创建编写器:

Reader in = new InputStreamReader(new FileInputStream('some_file.txt'),"UTF-8")
Writer out = new OutputStreamWriter(new FileOutputStream('some_file.txt'),"ISO-8859-1")
HTTP请求/响应也会发生类似的情况,这取决于应用服务器或浏览器对每个请求/响应的主体的解释方式,如果是这样的话,那么您可以在问题中添加一些细节。

这是一个示例

这里的问题是字符串是从字节创建的,使用了错误的字符集,该字符集假定一个字节是一个字符,如

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

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

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

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

您正在处理
µ
(U+00B5,微符号)和
(U+00C2,带扬抑符的拉丁文大写字母A)。这两个字符都属于

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

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

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

请注意,
µ
都可以在中表示,因此过滤一个而不是另一个是违反直觉的

UTF-8不是字符集。它是Unicode字符集的几种字符编码之一。UTF-16是另一种。这是Java的文本数据类型所使用的类型:String、char和Character。根据示例代码行之间的读取,在将文本放入字符串之前,您的文本似乎被某种程度地损坏了。往上游走,解决那个问题。如果您想提供有关上游流程的详细信息,请回答您的问题。
“100µF”
“100µF”
的UTF-8编码形式。Java字符串是UTF-16编码的。如果使用UTF-8以外的8位字符集将UTF-8数据错误地转换为UTF-16,则可以在
字符串中获得
“100µF”
。不要那样做!不要试图在转换后修复
“100µF”
以获得
“100µF”
(或任何其他类似的断串)。除非您能够确定用于破坏数据的错误字符集,否则猜测不会100%有效。首先,您需要修复导致您获得错误的
“100µF”
的逻辑错误。这是唯一正确分析的答案。然而,鉴于样本数据,不能确定是否应使用ISO 8859-1来修复损坏。我的系统有8个字符编码可以更正此示例:windows-1250、windows-1252、windows-1254、windows-1258、iso-8859-1、iso-8859-3、iso-8859-9和iso-8859-15。最多,其中一个可能是正确的@dev22intellial,如果你找不到错误的代码,你可以输入一个全面的测试数据集(比如一个字节为0-255的文件),并检测它是否可以通过一个字符编码进行反转。或者,假设
字符串是通过简单地将原始字节扩展到16位字符而创建的,而不考虑任何字符集,然后,您可以只分配一个长度相同的
字节[]
数组,然后将每个16位字符截断回一个8位字节。