R:需要用正则表达式替换 invisible/accented 个字符

R: need to replace invisible/accented characters with regex

我正在处理从具有不同语言环境设置的几台不同机器生成的文件,所以我最终得到了一个数据框的列,其中同一个词有不同的写法:

CÓRDOBA
CÓRDOBA
CÒRDOBA

我想将所有这些转换为 CORDOBA。我试过

t<-gsub("Ó|Ó|Ã’|°|°|Ò","O",t,ignore.case = T) # t is the vector of names

Wich 在找到一些 "invisible" 个字符之前一直有效:

如您所见,我无法在 R 中看到位于 Ã\ 之间的附加字符(如果我复制粘贴到 MS Word,word 显示它带有一个空的矩形)。我试过 dput 矢量,但它显示的与屏幕上的完全一样(没有 "invisible" 字符)。

I 运行 Encoding(t) 和 ir returns unknown 所有值。

我的系统配置如下:

> sessionInfo()
R version 3.2.1 (2015-06-18)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8 x64 (build 9200)

locale:
[1] LC_COLLATE=Spanish_Colombia.1252  LC_CTYPE=Spanish_Colombia.1252    LC_MONETARY=Spanish_Colombia.1252 LC_NUMERIC=C                     
[5] LC_TIME=Spanish_Colombia.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] zoo_1.7-12       dplyr_0.4.2      data.table_1.9.4

loaded via a namespace (and not attached):
 [1] R6_2.1.0        assertthat_0.1  magrittr_1.5    plyr_1.8.3      parallel_3.2.1  DBI_0.3.1       tools_3.2.1     reshape2_1.4.1  Rcpp_0.11.6     stringi_0.5-5  
[11] grid_3.2.1      stringr_1.0.0   chron_2.3-47    lattice_0.20-31

我已经 saveRDS 一个文件,其中包含玩具实际值和预期值的数据框,可能是 loadRDS 来自 here。我不确定它会加载我遇到的相同问题(取决于你的语言环境),但我希望它会加载,这样你就可以提供一些帮助。

最后,我想将所有这些特殊字符转换为无重音字符(ÓO,等等),希望不必手动输入每个特殊字符一个正则表达式(换句话说,如果可能的话,我想要某种 gsub("[:weird:]","[:equivalentToWeird:]",t)。如果不可能,至少我希望能够找到(并替换)那些 "invisible" 个字符。

谢谢,

##############编辑添加###################

如果我运行下面的代码:

d<-readRDS("c:/path/to(downloaded/Dropbox/file/inv_char.Rdata")
stri_escape_unicode(d$actual)

这是我得到的:

[1] "\u00c3\u201cN  N\u00c2\u00b0 08 \\"CACIQUE CALARC\u00c3\u0081\\" - ARMENIA"
[2] "\u00d3N  N\u00b0 08 \\"CACIQUE CALARC\u00c1\\" - ARMENIA"                     
[3] "\u00d3N  N\u00b0 08 \\"CACIQUE CALARC\u00c1\\" - ARMENIA(ALTERNO)" 

正常输出为:

> d$actual
[1] ÓN  N° 08 "CACIQUE CALARCÃ" - ARMENIA       ÓN  N° 08 "CACIQUE CALARCÁ" - ARMENIA          ÓN  N° 08 "CACIQUE CALARCÁ" - ARMENIA(ALTERNO)

在@hadley 的帮助下,他将我指向 stringi,我最终发现了违规字符并替换了它们。这是我最初的尝试:

unweird<-function(t){
    t<-stri_escape_unicode(t)
    t<-gsub("\\u00c3\\u0081|\\u00c1","A",t)
    t<-gsub("\\u00c3\\u02c6|\\u00c3\\u2030|\\u00c9|\\u00c8","E",t)
    t<-gsub("\\u00c3\\u0152|\\u00c3\\u008d|\\u00cd|\\u00cc","I",t)
    t<-gsub("\\u00c3\\u2019|\\u00c3\\u201c|\\u00c2\\u00b0|\\u00d3|\\u00b0|\\u00d2|\\u00ba|\\u00c2\\u00ba","O",t)
    t<-gsub("\\u00c3\\u2018|\\u00d1","N",t)
    t<-gsub("\u00a0|\u00c2\u00a0","",t)
    t<-gsub("\\u00f3","o",t)
    t<-stri_unescape_unicode(t)
}

产生了预期的结果。我对其他 stringi 函数有点好奇,所以我想知道它的替代函数是否可以在我的 330 万行中更快。然后我像这样尝试 stri_replace_all_regex

stri_unweird<-function(t){
  stri_unescape_unicode(stri_replace_all_regex(stri_escape_unicode(t),
    c("\\u00c3\\u0081|\\u00c1",
      "\\u00c3\\u02c6|\\u00c3\\u2030|\\u00c9|\\u00c8",
      "\\u00c3\\u0152|\\u00c3\\u008d|\\u00cd|\\u00cc",
      "\\u00c3\\u2019|\\u00c3\\u201c|\\u00c2\\u00b0|\\u00d3|\\u00b0|\\u00d2|\\u00ba|\\u00c2\\u00ba",
      "\\u00c3\\u2018|\\u00d1",
      "\u00a0|\u00c2\u00a0",
      "\\u00f3"),
   c("A","E","I","O","N","","o"),
   vectorize_all = F))
}

作为旁注,我 运行 microbenchmark 两种方法,结果如下:

g<-microbenchmark(unweird(t),stri_unweird(t),times = 100L)
summary(g)
       min       lq     mean   median       uq      max neval cld
1 423.0083 425.6400 431.9609 428.1031 432.6295 490.7658   100   b
2 118.5831 119.5057 121.2378 120.3550 121.8602 138.3111   100  a