java中UTF-8到ASCII的转换
我有一个字符串包含UTF-8字符集格式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
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位字节。