转换R中的HTML字符实体编码

use*_*626 20 html encoding r character-encoding

R中有没有办法转换HTML字符实体编码?

我想HTML字符实体转换喜欢 &&>>

对于Perl存在的包HTML :: Entities可以做到这一点,但我在R中找不到类似的东西.

我也尝试过iconv()但无法获得令人满意的结果.也许还有一种方法可以使用这个XML包,但我还没想出来.

Jer*_*oen 20

使用xml2包的Unescape xml/html值:

unescape_xml <- function(str){
  xml2::xml_text(xml2::read_xml(paste0("<x>", str, "</x>")))
}

unescape_html <- function(str){
  xml2::xml_text(xml2::read_html(paste0("<x>", str, "</x>")))
}
Run Code Online (Sandbox Code Playgroud)

例子:

unescape_xml("3 &lt; x &amp; x &gt; 9")
# [1] "3 < x & x > 9"
unescape_html("&euro; 2.99")
# [1] "€ 2.99"
Run Code Online (Sandbox Code Playgroud)


Ton*_*yal 19

更新:这个答案已经过时了.请根据新的xml2 pkg 检查以下答案.


尝试以下方面的事情:

# load XML package
library(XML)

# Convenience function to convert html codes
html2txt <- function(str) {
      xpathApply(htmlParse(str, asText=TRUE),
                 "//body//text()", 
                 xmlValue)[[1]] 
}

# html encoded string
( x <- paste("i", "s", "n", "&", "a", "p", "o", "s", ";", "t", sep = "") )
[1] "isn&apos;t"

# converted string
html2txt(x)
[1] "isn't"
Run Code Online (Sandbox Code Playgroud)

更新:编辑html2txt()函数,以便它适用于更多情况


Sti*_*ibu 8

虽然Jeroen 的解决方案可以完成这项工作,但它的缺点是它不是矢量化的,因此如果应用于大量字符,速度会很慢。此外,它仅适用于长度为 1 的字符向量,并且必须使用sapply更长的字符向量。

\n\n

为了演示这一点,我首先创建一个大字符向量:

\n\n
set.seed(123)\nstrings <- c("abcd", "&amp; &apos; &gt;", "&amp;", "&euro; &lt;")\nmany_strings <- sample(strings, 10000, replace = TRUE)\n
Run Code Online (Sandbox Code Playgroud)\n\n

并应用该函数:

\n\n
unescape_html <- function(str) {\n  xml2::xml_text(xml2::read_html(paste0("<x>", str, "</x>")))\n}\n\nsystem.time(res <- sapply(many_strings, unescape_html, USE.NAMES = FALSE))\n##    user  system elapsed \n##   2.327   0.000   2.326 \nhead(res)\n## [1] "& \' >" "\xe2\x82\xac <"   "& \' >" "\xe2\x82\xac <"   "\xe2\x82\xac <"   "abcd" \n
Run Code Online (Sandbox Code Playgroud)\n\n

如果将字符向量中的所有字符串组合成一个大字符串,则速度会快得多,这样read_html()xml_text()只需要使用一次。然后可以使用以下命令轻松地再次分离字符串strsplit()

\n\n
unescape_html2 <- function(str){\n  html <- paste0("<x>", paste0(str, collapse = "#_|"), "</x>")\n  parsed <- xml2::xml_text(xml2::read_html(html))\n  strsplit(parsed, "#_|", fixed = TRUE)[[1]]\n}\n\nsystem.time(res2 <- unescape_html2(many_strings))\n##    user  system elapsed \n##   0.011   0.000   0.010 \nidentical(res, res2)\n## [1] TRUE\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,您需要小心,用于组合str"#_|"在我的示例中)中的各个字符串的字符串不会出现在 中的任何位置str。否则,当最后再次分割大字符串时,您将引入错误。

\n