似乎有一些R库函数可以猜测字符编码,例如stringi::stri_enc_detect
,但如果可能的话,最好使用简单的确定性方法按顺序尝试固定集合的编码方式。看起来最好的方法是利用iconv
在转换字符串时无法转换时返回NA
的事实。
linewise.decode = function(path)
sapply(readLines(path), USE.NAMES = F, function(line) {
if (validUTF8(line))
return(line)
l2 = iconv(line, "Windows-1252", "UTF-8")
if (!is.na(l2))
return(l2)
l2 = iconv(line, "Shift-JIS", "UTF-8")
if (!is.na(l2))
return(l2)
stop("Encoding not detected")
})
如果您创建了一个测试文件,其中包含
$ python3 -c 'with open("inptest", "wb") as o: o.write(b"This line is ASCII\n" + "This line is UTF-8: I like π\n".encode("UTF-8") + "This line is Windows-1252: Müller\n".encode("Windows-1252") + "This line is Shift-JIS: ハローワールド\n".encode("Shift-JIS"))'
然后linewise.decode("inptest")
确实返回
[1] "This line is ASCII"
[2] "This line is UTF-8: I like π"
[3] "This line is Windows-1252: Müller"
[4] "This line is Shift-JIS: ハローワールド"
要使用
linewise.decode
与
XML::readHTMLTable
一起,只需像这样说:
XML::readHTMLTable(linewise.decode("http://example.com"))
。