我正在研究将字符串从一个字符集转换为另一个字符集,阅读了很多关于它的示例,最终找到了下面的代码,这对我来说很好,作为一个字符集编码的新手,我想知道,这是否是正确的方法。
public static byte[] transcodeField(byte[] source, Charset from, Charset to) {
return new String(source, from).getBytes(to);
}
要将字符串从ASCII转换为EBCDIC,我必须执行以下操作:
System.out.println(new String(transcodeField(ebytes,
Charset.forName("US-ASCII"), Charset.forName("Cp1047"))));
要将EBCDIC转换为ASCII,我必须:
System.out.println(new String(transcodeField(ebytes,
Charset.forName("Cp1047"), Charset.forName("US-ASCII"))));
您找到的代码(transcodeField
)不会将String
从一种编码转换为另一种编码,因为String
没有编码。它将字节从一种编码转换为另一种编码。只有当你的用例满足两个条件时,该方法才有用:
在这种情况下,这是直截了当的:
byte[] out = transcodeField(inbytes, Charset.forName(inEnc), Charset.forName(outEnc));
如果输入数据包含不能在输出编码中表示的字符(例如将复杂的UTF8
转换为ASCII
),这些字符将被替换为?
替换符号,并且数据将被损坏。
然而,很多人问“如何将字符串从一种编码转换为另一种编码”,对此很多人用以下片段回答:
String s=新字符串(source.getBytes(inputEncoding),outputEncoding)
这完全是胡说八道。
getBytes(String encoding)
方法返回一个字节数组,其中包含按指定编码编码的字符(如果可能,无效字符也会被转换为?
)。带有第2个参数的字符串构造函数从字节数组创建一个新字符串,其中字节采用指定的编码。既然你刚刚使用了源代码。getBytes(inputEncoding)
要获取这些字节,它们不在OutpuneCoding
中编码(除非编码使用相同的值,这对于像abcd
这样的“普通”字符很常见,但与更复杂的重音字符不同。
那么这意味着什么呢?这意味着当你有一个Java
字符串时,一切都很好<代码>字符串
是unicode,这意味着所有字符都是安全的。当您需要将字符串
转换为字节时,就会出现问题,这意味着您需要决定编码方式。选择与unicode兼容的编码,例如UTF8
,UTF16
等,这是非常好的选择。这意味着即使字符串中包含各种奇怪的字符,您的字符仍然是安全的。如果选择不同的编码(支持度最低的是US-ASCII
),则字符串必须仅包含编码支持的字符,否则将导致字节损坏。
现在最后是一些好的和坏的用法的例子。
String myString = "Feng shui in chinese is 風水";
byte[] bytes1 = myString.getBytes("UTF-8"); // Bytes correct
byte[] bytes2 = myString.getBytes("US-ASCII"); // Last 2 characters are now corrupted (converted to question marks)
String nordic = "Här är några merkkejä";
byte[] bytes3 = nordic.getBytes("UTF-8"); // Bytes correct, "weird" chars take 2 bytes each
byte[] bytes4 = nordic.getBytes("ISO-8859-1"); // Bytes correct, "weird" chars take 1 byte each
String broken = new String(nordic.getBytes("UTF-8"), "ISO-8859-1"); // Contains now "Här är några merkkejä"
最后一个示例演示了即使两种编码都支持北欧字符,但它们使用不同的字节来表示它们,并且在解码Mojibake结果时使用了错误的编码。因此,不存在“将字符串从一种编码转换为另一种编码”这样的事情,并且您永远不应该使用破碎的示例。
还请注意,您应该始终指定所使用的编码(同时使用
getBytes()
和new String()
),因为您不能相信默认编码总是您想要的编码。
最后一个问题是,字符集和编码不是一回事,但它们有很大的关联。
从技术上讲,字符串在JVM内部存储的方式是UTF-16编码,最高Java8,从Java9开始的变量编码,但是开发人员不需要关心这个。
注意事项
有可能有一个损坏的字符串,并且能够通过摆弄编码来解除它的损坏,这可能是这种“将字符串转换为其他编码”误解的起源。
// Input comes from network/file/other place and we have misconfigured the encoding
String input = "Här är några merkkejä"; // UTF-8 bytes, interpreted wrongly as ISO-8859-1 compatible
byte[] bytes = input.getBytes("ISO-8859-1"); // Get each char as single byte
String asUtf8 = new String(bytes, "UTF-8"); // Recreate String as UTF-8
如果
输入
中没有损坏字符,字符串现在将被“修复”。然而,正确的方法是在读取输入时使用正确的编码,而不是事后修复。尤其是如果它有可能被腐蚀的话。
假设我有以下数组列表: 并且必须遵守规则: 从数组列表 1 开始,我想形成新的以下数组列表: <李>猫狗 <李>鼠蛇 无论如何都可以这样做。我目前还没有找到任何字符串到字符串转换的内容。
问题内容: 我有以下数据框 我想更换和使用,所以最终的数据帧 我尝试了以下操作,但没有成功: 问题答案: 解决方案与通过: 如果需要将列中的所有值设置为一些:
我对任何编程都非常陌生,所以请原谅我的无知,因为我不知道如何做一些看起来很简单的事情。 我所要做的就是获取任何字符串数组(称之为名称),比如: 并将其从列表中删除,并将其转换为字符串: 我似乎无法理解这一点,也找不到类似的帖子。
我有以下数据框 我想用替换和,因此最终的数据帧是 我尝试了以下方法,但不起作用:
我正在解决“HackerRank”页面上的一个问题,特别是名为“Append and Delete”的问题,但我无法使所有情况都正确。 https://www.hackerrank.com/challenges/append-and-delete/problem “您有一个小写英文字母字符串。您可以对该字符串执行两种类型的操作: 在字符串的末尾附加一个小写英文字母。删除字符串中的最后一个字符。对空