【问题标题】:convert utf8 code point strings like <U+0161> to utf8将 <U+0161> 等 utf8 代码点字符串转换为 utf8
【发布时间】:2017-02-12 08:31:09
【问题描述】:

我有一个文本文件,其中包含某种 Unicode 字符的回退转换(尖括号中的 Unicode 代码点)。所以它包含例如foo&lt;U+017E&gt;bar 应该是“foošbar”。 R中是否有一种简单的方法可以将整个文件转换为UTF8并转换这些字符?不幸的是,我在 Windows 上,找不到受支持的 UTF-8 语言环境。

【问题讨论】:

  • UTF8 是一种编码,NOT 是一种语言环境。无论如何,Windows 至少从 2000 年开始就使用 Unicode。 R 包虽然混合了 Unicode 和 ANSI 代码,但依赖于更改本地化设置来处理编码问题。你实际上尝试了什么?不同的包有不同的怪癖。不幸的是,其中一些混淆了语言和编码
  • 文件的编码和内容是什么?它是否使用其中一种 Unicode 编码?然后它可以包含foošbar 而没有任何转换问题。您确定问题不是 RStudio 或 RRO 的显示字体吗?
  • 我的问题是我无法在 Windows 上切换到 UTF-8 友好的语言环境; Sys.setlocale("LC_ALL", 'en_US.UTF-8') 之类的东西不起作用,不知道为什么。所以无论文件的编码是什么,我都有这个问题。
  • Locales 与国家有关,而不是 Unicode 编码。 Sys.setlocale 实际上是一种 R 解决方法,它允许 ANSI 编译的包使用 Unicode 数据——只要它们不尝试检查这些值。例如,我从文件中输入或加载foošbar 没有问题。一些包虽然无法处理加载的文本,而其他包则没有问题。有些甚至混合了 Unicode 和 ANSI 代码
  • 什么显示问题的代码?替换字符串只是一种解决方法。

标签: r utf-8


【解决方案1】:

当代码点恰好显示为四位数字时,前面的答案应该有效。这是一个修改后的版本,适用于 1 到 8 之间的任意位数。

library(stringi)
library(magrittr)

"foo<U+0161>bar and cra<U+017E>y, Phoenician letter alf <U+10900>" %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{4})>", "\\\\u$1") %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{5})>", "\\\\U000$1") %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{6})>", "\\\\U00$1") %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{7})>", "\\\\U0$1") %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{8})>", "\\\\U$1") %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{1})>", "\\\\u000$1") %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{2})>", "\\\\u00$1") %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]{3})>", "\\\\u0$1") %>% 
  stri_unescape_unicode() %>% 
  stri_enc_toutf8()
## [1] "foošbar and cražy, Phoenician letter alf ?"

【讨论】:

  • 但是前面的答案不应该也适用于任意位数吗?我的意思是 [[:alnum:]] 表示任何字母数字字符,+ 表示一次或多次。 (当然可能是你回答后才编辑的……)
  • 小写转义码\u 最多接受四位数字。例如,另一个答案中提出的解决方案将无法正确处理"&lt;U+102A0&gt;",将其转换为\u102A0,即字符&lt;U+102A&gt; 后跟文字零。此外,如果代码点异常没有零填充到四位,则会出现问题:stri_unescape_unicode() 要求 \u 后跟四位(\U 后跟八位)。
  • 该死,我明白你在说什么!正则表达式本身会提取所有内容,但是在这种情况下,它替换模式的内容是不可使用的。尽管 R 可以使用带有“最多 8 个”字符的 \U(如果我打印 "\U102A0",R 会输出 "\U000102a0"),stri_unescape_unicode 非常严格:它需要 \u1234\U12345678\U102A0 引发错误。我很高兴我问了;谢谢!
  • 也就是说,我也不能只用stri_replace_all_regex("&lt;U\\+([[:alnum:]]{1,8})&gt;", "\\\\U$1")代替原来的解决方案。
【解决方案2】:

也许:

library(stringi)
library(magrittr)

"foo<U+0161>bar and cra<U+017E>y" %>% 
  stri_replace_all_regex("<U\\+([[:alnum:]]+)>", "\\\\u$1") %>% 
  stri_unescape_unicode() %>% 
  stri_enc_toutf8()
## [1] "foošbar and cražy"

可能有效(我不需要在 macOS 上进行最后一次转换,但您可以在 Windows 上进行)。

【讨论】:

  • 无需转换,Windows 原生使用 Unicode。另一方面,R 包将 Unicode 和 ANSI 代码混为一谈。更糟糕的是,许多 R 包不识别编码,而是尝试从系统的区域设置或语言中猜测。当尝试读取多种 Unicode 编码,甚至多种日期和数字格式时,这让事情变得有趣
猜你喜欢
  • 1970-01-01
  • 2014-01-29
  • 2010-12-04
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
相关资源
最近更新 更多