解析操作系统与list.files()处理重音字符

时间:2018-05-06 21:22:39

标签: r locale filenames

我正在纠正那些在名字中加入字符(而不是我的家庭语言环境)的学生的家庭作业,并愚蠢地决定在用我的评论(Firstname.Lastname)创建文件时尊重他们名字的实际拼写。通常,我创建了文件名(在控制台中或在Emacs中使用Compose Key(例如compose-'-a生成á)。这导致操作系统和R list.files()之间出现以下不匹配。 :

system("touch testá")      ## create file with accented character in name
list.files(pattern="test") ## it's there ...
## [1] "testá"

但是当我尝试匹配pattern参数中的整个单词时......

list.files(pattern="testá")
## character(0)

这是在Xubuntu 16.04上,但它是一个虚拟机,因此底层文件系统是HFS。我的正常语言环境是

[1] "LC_CTYPE=en_CA.UTF8;LC_NUMERIC=C;LC_TIME=en_CA.UTF8;LC_COLLATE=en_CA.UTF8;LC_MONETARY=en_CA.UTF8;LC_MESSAGES=en_CA.UTF8;LC_PAPER=en_CA.UTF8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_CA.UTF8;LC_IDENTIFICATION=C"

但通过Sys.setlocale("LC_ALL","pl_PL.UTF8")(显然成功)切换它并没有帮助。

对我来说真正奇怪的是,用“testł”做同样的练习工作......

正如评论中所建议的,我使用charToRaw进行了更多探讨。事实上,R中的字符串表示与存储在磁盘上的名称之间存在差异:

charToRaw("testá")
## [1] 74 65 73 74 c3 a1
charToRaw(list.files(pattern="test"))
## [1] 74 65 73 74 61 cc 81

2 个答案:

答案 0 :(得分:1)

我在Mac上和你一样。尝试给出一个“test \ u00e1”的模式,这是我的as.hexmode(utf8ToInt("á"))所说的ASCII值:

结束了对手头问题的强力建议。

> file.rename("testá", "testXXX")
[1] TRUE
> list.files(pattern="testXXX")
[1] "testXXX"

和Y Yoda一样,我第一次看到charToRaw并收到了错误的翻译,我明白了:

> "\u00e1"
[1] "á"
> "test\uc3a1"
[1] "test쎡"

答案 1 :(得分:1)

感谢来自@ 42-和@RYoda的线索:由于我的基础文件系统是HFS +,我能够找到这个blog post on "HFS+ and utf8 accented characters",这导致我this SO question & answer on Unicode normalization,这导致了解决方案< / p>

list.files(pattern=stringi::stri_trans_nfd("testá"))

?stri_trans_nfd让我们知道&#34; nfd&#34;代表

  

•NFD(Canonical Decomposition),