将 ISO-8859-1 / Latin-1 转换为字符串 (UTF-8) 的选项都有哪些?
Posted
技术标签:
【中文标题】将 ISO-8859-1 / Latin-1 转换为字符串 (UTF-8) 的选项都有哪些?【英文标题】:What are the options to convert ISO-8859-1 / Latin-1 to a String (UTF-8)?将 ISO-8859-1 / Latin-1 转换为字符串 (UTF-8) 的选项有哪些? 【发布时间】:2015-03-26 00:35:07 【问题描述】:我扫描了 Rust 文档以寻找某种在字符编码之间进行转换的方法,但没有找到任何东西。我错过了什么吗?
Rust 语言及其标准库是否支持(直接或间接),甚至计划在不久的将来支持?
正如其中一个答案所暗示的,有一个简单的解决方案,因为u8
可以转换为(Unicode)char
s。由于 Unicode 是 ISO-8859-1 中代码点的超集,这是一个 1:1 映射,它编码为 UTF-8 中的多个字节,这是 Rust 中 String
s 的内部编码。
fn main()
println!("", 196u8 as char);
println!("", (196u8 as char) as u8);
println!("", 'Ä' as u8);
println!(":?", 'Ä'.to_string().as_bytes());
println!(":?", "Ä".as_bytes());
println!("",'Ä' == 196u8 as char);
给予:
Ä
196
196
[195, 132]
[195, 132]
true
我什至没有考虑过工作!
【问题讨论】:
对于 Rust,很难分辨什么是“标准库”,什么不是,因为这可能每天都在变化 :) 确实如此,但在这种情况下,我可以看到关注二进制大小的人对在每个已知字符编码之间嵌入转换算法的想法感到畏缩。 【参考方案1】:Rust 中的字符串是 unicode (UTF-8),而 unicode 代码点是 iso-8859-1 字符的超集。这个具体的转换其实是微不足道的。
fn latin1_to_string(s: &[u8]) -> String
s.iter().map(|&c| c as char).collect()
我们将每个字节解释为一个 unicode 代码点,然后从这些代码点构建一个字符串。
【讨论】:
既然我被这个绊倒了,请注意“只有代码点 0 - 127 的编码相同;代码点 128 - 255 的不同之处在于它们是 UTF-8 的 2 字节序列,而它们是单字节使用拉丁语 1" (source)。这意味着您不能简单地将 ISO-8859-1 中的u8
片段重新解释为 UTF-8。
是的,“编码为 UTF-8”,但代码点本身是相同的。这就是使他的答案成为将 ISO-8859-1 编码为 UTF-8 的完美解决方案的原因。就像使用“as char”将每个 ISO-8859-1 字节转换为 char 一样简单。我的特殊情况处理 ISO-8859-15,这意味着我们必须以不同的方式转换一些字符。【参考方案2】:
标准库没有任何 API 来处理编码。编码,如日期和时间,很难正确处理,需要大量工作,因此std
中不存在它们。
目前处理编码的 crate 是 rust-encoding。您几乎肯定会在那里找到所需的一切。
【讨论】:
是的......这就是我们已经使用的。我只是想仔细检查一下我们是否对当前的标准库进行了任何疏忽。我也知道 IO 大修发生了一些事情。但据我所知,此讨论不涉及除 UNICODE 表示之外的其他编码。 不,我不认为编码是 I/O 重新实现的一部分。此外,AFAIK 很难获得像 Java 的InputStreamReader
/OutputStreamWriter
这样带有 rust-encoding 的流解码器/编码器,因此肯定还有改进的空间。
"标准库没有任何 API 来处理编码。"什么?它有大量的 API 来处理 UTF-8,还有一些处理 UTF-16。以上是关于将 ISO-8859-1 / Latin-1 转换为字符串 (UTF-8) 的选项都有哪些?的主要内容,如果未能解决你的问题,请参考以下文章