我有一个包含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”
答案 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表示,因此过滤一个而不过滤另一个是很不直观的。