конвертировать кодировку HTML-сущности в R - PullRequest
20 голосов
/ 21 февраля 2011

Есть ли способ в R преобразовать кодировки символьных сущностей HTML?

Я хотел бы преобразовать символьные объекты HTML, такие как & до & или > до >

Для Perl существует пакет HTML :: Entities, который мог бы это сделать, но я не смог найти что-то похожее в R.

Я также пытался iconv(), но не мог получить удовлетворительные результаты. Может быть, есть способ использовать пакет XML, но я еще не понял.

Ответы [ 3 ]

19 голосов
/ 04 февраля 2016

Unescape xml / html-значения с использованием пакета xml2:

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>")))
}

Примеры:

unescape_xml("3 &lt; x &amp; x &gt; 9")
# [1] "3 < x & x > 9"
unescape_html("&euro; 2.99")
# [1] "€ 2.99"
19 голосов
/ 21 февраля 2011

Обновление : этот ответ устарел. Пожалуйста, проверьте ответ ниже на основе новой 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"

ОБНОВЛЕНИЕ: отредактировал функцию html2txt (), чтобы она применялась в других ситуациях

2 голосов
/ 13 августа 2018

Хотя решение от Jeroen выполняет свою работу, оно имеет недостаток, заключающийся в том, что оно не векторизовано и поэтому медленное, если применяется к большому количеству символов.Кроме того, он работает только с вектором символов длиной один и нужно использовать sapply для более длинного вектора символов.

Чтобы продемонстрировать это, я сначала создаю большой вектор символов:

set.seed(123)
strings <- c("abcd", "&amp; &apos; &gt;", "&amp;", "&euro; &lt;")
many_strings <- sample(strings, 10000, replace = TRUE)

И примените функцию:

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

system.time(res <- sapply(many_strings, unescape_html, USE.NAMES = FALSE))
##    user  system elapsed 
##   2.327   0.000   2.326 
head(res)
## [1] "& ' >" "€ <"   "& ' >" "€ <"   "€ <"   "abcd" 

Это намного быстрее, если все строки в символьном векторе объединить в одну большую строку, так что read_html() и xml_text() нужно толькоиспользоваться один раз.Затем строки можно легко снова разделить, используя strsplit():

unescape_html2 <- function(str){
  html <- paste0("<x>", paste0(str, collapse = "#_|"), "</x>")
  parsed <- xml2::xml_text(xml2::read_html(html))
  strsplit(parsed, "#_|", fixed = TRUE)[[1]]
}

system.time(res2 <- unescape_html2(many_strings))
##    user  system elapsed 
##   0.011   0.000   0.010 
identical(res, res2)
## [1] TRUE

Конечно, вам нужно быть осторожным, чтобы строка, которую вы используете для объединения различных строк в str ("#_|" вмой пример) нигде не появляется в str.В противном случае вы введете ошибку, когда большая строка снова разделится в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...