使用混合字符编码读取R中的文件

时间:2019-06-03 14:56:24

标签: html r character-encoding

我正在尝试将表格从大多数以UTF-8编码(并声明<meta charset="utf-8">)的HTML页面读入R中,但是在某些其他编码中有一些字符串(我认为Windows-1252或ISO 8859- 1)。 Here's an example.我希望所有内容都正确解码为R数据帧。 XML::readHTMLTable接受一个encoding参数,但似乎不允许尝试多种编码。

因此,在R中,如何为输入文件的每一行尝试几种编码?在Python 3中,我会做类似的事情:

with open('file', 'rb') as o:
    for line in o:
        try:
            line = line.decode('UTF-8')
        except UnicodeDecodeError:
            line = line.decode('Windows-1252')

1 个答案:

答案 0 :(得分:4)

似乎有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.decodeXML::readHTMLTable一起使用,只需说类似XML::readHTMLTable(linewise.decode("http://example.com"))之类的话。