如何将UTF-8中的字符串转换为ASCII并忽略错误并删除非ASCII字符

时间:2018-07-27 22:24:30

标签: scala character-encoding

我是Scala的新手。

请告知如何将UTF-8中的字符串转换为ASCII,而忽略错误并删除输出中的非ASCII字符。

例如,如何从结果字符串“hello.��”中删除非ASCII字符\ uc382,以便在输出中打印“ hello”。

scala.io.Source.fromBytes("hello\uc382".getBytes ("UTF-8"), "US-ASCII").mkString

2 个答案:

答案 0 :(得分:1)

val str = "hello\uc382"
str.filter(_ <= 0x7f) // keep only valid ASCII characters

答案 1 :(得分:0)

如果您现在以字符串形式将UTF-8中的文本作为字节,则将其转换。

如果字符串中包含文本,并且希望将ASCII文本作为字节,则可以稍后进行转换。

似乎您只想为C0 Controls and Basic Latin代码点过滤UTF-16代码单元。幸运的是,此类代码点仅占用一个代码单元,因此我们可以直接对其进行过滤,而无需将其转换为代码点。

"hello\uC382"
  .filter(Character.UnicodeBlock.of(_) == Character.UnicodeBlock.BASIC_LATIN)
  .getBytes(StandardCharsets.US_ASCII)
  .foreach { 
    println }

由于问题被普遍化为任意的已知字符编码,因此过滤不起作用。相反,可以使用编码器的功能来忽略目标Charset中不存在的字符。编码器需要更多的包装和展开。 (API设计基于在同一流甚至其他流中流式传输和重新使用缓冲区。)因此,以ISO_8859_1为例:

val encoder = StandardCharsets.ISO_8859_1
  .newEncoder() 
  .onMalformedInput(CodingErrorAction.IGNORE)
  .onUnmappableCharacter(CodingErrorAction.IGNORE)

val string = "ñhello\uc382"
println(string)
val chars = CharBuffer.allocate(string.length())
  .put(string)
chars.rewind()
val buffer = encoder.encode(chars)
val bytes = Array.ofDim[Byte](buffer.remaining())
buffer.get(bytes)
println(bytes)
bytes
  .foreach { 
    println }