Подтвердить что ты не робот

Конвертировать кодировку символов символа HTML в R

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

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

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

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

4b9b3361

Ответ 1

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

UPDATE: отредактирована функция html2txt(), поэтому она применима к большему количеству ситуаций

Ответ 2

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"

Ответ 3

Хотя решение 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. В противном случае вы введете ошибку, когда большая строка будет снова разделена в конце.