Конвертировать кодировку символов символа HTML в R
Есть ли способ в R для преобразования кодовых имен символов HTML?
Я хотел бы преобразовать объекты символа HTML, например
&
до &
или
>
до >
Для Perl существует пакет HTML:: Entities, который мог бы это сделать, но я не мог найти что-то подобное в R.
Я также пробовал iconv()
, но не смог получить удовлетворительные результаты. Возможно, есть и способ использования пакета XML
, но я еще не понял его.
Ответы
Ответ 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'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 < x & x > 9")
# [1] "3 < x & x > 9"
unescape_html("€ 2.99")
# [1] "€ 2.99"
Ответ 3
Хотя решение Jeroen выполняет эту работу, у него есть недостаток, что он не является векторизованным и, следовательно, медленным, если применяется к большому числу символов. Кроме того, он работает только с символьным вектором длины один, и один должен использовать sapply
для более длинного символьного вектора.
Чтобы продемонстрировать это, я сначала создаю вектор большого символа:
set.seed(123)
strings <- c("abcd", "& ' >", "&", "€ <")
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
. В противном случае вы введете ошибку, когда большая строка будет снова разделена в конце.