由于R中的语言特殊字符,如何更正字符串中的额外字符?

时间:2015-04-04 17:44:03

标签: r encoding double-byte

我有两个几乎等效的字符串。它们看起来一样。

str1<-"Diş Hekimliği Fakültesi"
str2<-"Diş Hekimliği Fakültesi"

但是当我对它们尝试nchar()时,它们分别返回26和23个字符。当我使用strsplit();

strsplit(str1,split="")
[[1]]
 [1] "D" "i" "s" "̧"   " " "H" "e" "k" "i" "m" "l" "i" "g" "̆"   "i" " " "F" "a" "k" "u" "̈"   "l" "t" "e" "s" "i"

strsplit(str2,split="")
[[1]]
 [1] "D" "i" "ş" " " "H" "e" "k" "i" "m" "l" "i" "ğ" "i" " " "F" "a" "k" "ü" "l" "t" "e" "s" "i"

每种语言特定的特殊字符都计为两个字符。如何将str1转换为str2?我唯一的手动解决方案是使用gsub()

PS。不幸的是,我不能把这个例子全部带到这里。当你尝试复制粘贴代码时,它将是23个characers。这里复制粘贴的东西。

1 个答案:

答案 0 :(得分:0)

iconv函数是一个特定于系统的函数,用于管理国际编码之间的音译。有一个函数iconvlist可以返回操作系统工具使用的名称向量;我在sapplytry的帮助下在我的系统上运行了所有419个这样的编码,看看我是否可以将str1(23个字符)的转换为26,反之亦然,并在我的网上找到两个这样的编码机。由于我使用Mac,因此您无法保证这些特定值对您有用,因为您不会透露您的操作系统状态:

我能够只使用strsplit的结果汇总一个MWE - 来自上面str2的结果:

str1<-"Diş Hekimliği Fakültesi"
str3 <- scan(what="")
 "D" "i" "s" "̧"   " " "H" "e" "k" "i" "m" "l" "i" "g" "̆"   "i" " " "F" "a" "k" "u" "̈"   "l" "t" "e" "s" "i"
#27: 
#Read 26 items
> str3c <- paste0(str3, collapse="")
> nchar(str3c)
[1] 26
> str1
[1] "Diş Hekimliği Fakültesi"

在许多错误消息(由于封闭try()而没有停止执行)之后,我使用此代码获得了2个编码的列表:

?iconv
which(sapply( try(utils::head(iconvlist(), n = 419)), function(xc) 
                                                  try(nchar(iconv(str1, to=xc))))==26)
#--------snipped large number of error messages-------
Error in nchar(iconv(str1, to = xc)) : invalid multibyte string 1
UTF-8-MAC  UTF8-MAC 
      400       402 

然后认为反向可能成功(因为str1以23-char对象开始)我成功尝试过:

> iconv(str3c,from="UTF-8-MAC", to="UTF-8")
[1] "Diş Hekimliği Fakültesi"
> nchar(iconv(str3c,from="UTF-8-MAC", to="UTF-8"))
[1] 23

查看webpages for the Windows iconv,可以看到{10081, "x-mac-turkish"}, /* Turkish (Mac) */有一个列表。如果您使用的是Windoze,也许可以尝试一下。

=====

下面的早期调查(我认为知道如何拆分字符值很有用。)

行。我实际上可以将MWE与上面的东西组合在一起:

str1<-"Diş Hekimliği Fakültesi"
str3 <- scan(what="")
#1: "D" "i" "s" "̧"   " " "H" "e" "k" "i" "m" "l" "i" "g" "̆"   "i" " " "F" "a" "k" "u" "̈"   "l" "t" "e" "s" "i"
#27: 
#Read 26 items
> str3c <- paste0(str3, collapse="")
> nchar(str3c)
[1] 26
> str1
[1] "Diş Hekimliği Fakültesi"

现在要做一些角色黑客攻击:

> ?charToRaw
> charToRaw(str3c)
 [1] 44 69 73 cc a7 20 48 65 6b 69 6d 6c 69 67 cc 86 69 20 46 61 6b 75 cc 88 6c 74 65
[28] 73 69
> charToRaw(str1)
 [1] 44 69 c5 9f 20 48 65 6b 69 6d 6c 69 c4 9f 69 20 46 61 6b c3 bc 6c 74 65 73 69

请查看代表您第三个字母的三个Raw项目。似乎第二个表示使用了一个基本字符,它用十六进制对其进行退格。&#34; cc&#34;然后打印下降器。现在看看我们是否可以用正则表达式识别它们:

 rawToChar( charToRaw(str3c) [3])
#[1] "s"
 rawToChar( charToRaw(str3c) [4])
#[1] "\xcc"
 rawToChar( charToRaw(str3c) [5])
#[1] "\xa7"
 grep("s\\xcc\\xa7", str3c)
#[1] 1   # Success!

如果你正在使用这些词的拆分版本,我认为这里的gsub可能比你最终得到的效率更高:

gsub("s\\xcc\\xa7", "\\c5\\9f", str3c)
#[1] "Diş Hekimliği Fakültesi"

另请注意,在一个R中实际上有29个原始条目告诉您有26个&#34;字符&#34; (据说有23个人中的26个)。我认为实际上没有计算三个cc(退格)。