Преобразование \u экранированной строки Unicode в ASCII
Прочитав все о iconv
а также Encoding
Я все еще в замешательстве.
Я очищаю источник веб-страницы, у меня есть строка, которая выглядит так: 'pretty\u003D\u003Ebig'
(отображается в консоли R как 'pretty\\\u003D\\\u003Ebig'
). Я хочу преобразовать это в строку ASCII, которая должна быть 'pretty=>big'
,
Проще говоря, если я установлю
x <- 'pretty\\u003D\\u003Ebig'
Как мне выполнить конвертацию на x
уступать pretty=>big
?
Какие-либо предложения?
7 ответов
Используйте анализ, но не оценивайте результаты:
x1 <- 'pretty\\u003D\\u003Ebig'
x2 <- parse(text = paste0("'", x1, "'"))
x3 <- x2[[1]]
x3
# [1] "pretty=>big"
is.character(x3)
# [1] TRUE
length(x3)
# [1] 1
С stringi
пакет:
> x <- 'pretty\\u003D\\u003Ebig'
> stringi::stri_unescape_unicode(x)
[1] "pretty=>big"
Хотя я принял ответ Хон Хои, я не могу не думать parse
а также eval
это тяжеловесное решение. Кроме того, как указано выше, это небезопасно, хотя для моего приложения я могу быть уверен, что не получу опасных цитат.
Итак, я разработал альтернативный, несколько жестокий подход:
udecode <- function(string){
uconv <- function(chars) intToUtf8(strtoi(chars, 16L))
ufilter <- function(string) {
if (substr(string, 1, 1)=="|") uconv(substr(string, 2, 5)) else string
}
string <- gsub("\\\\u([[:xdigit:]]{4})", ",|\\1,", string, perl=TRUE)
strings <- unlist(strsplit(string, ","))
string <- paste(sapply(strings, ufilter), collapse='')
return(string)
}
Любые упрощения приветствуются!
Использование для eval(parse)
!
eval(parse(text=paste0("'", x, "'")))
Конечно, у этого есть свои проблемы, такие как необходимость вручную экранировать любые кавычки в строке. Но это должно работать для любых допустимых последовательностей Unicode, которые могут появиться.
Я сочувствую; Я боролся с R и текстом Unicode в прошлом и не всегда успешно. Если ваши данные находятся в x
затем сначала попробуйте глобальную замену, что-то вроде этого:
x <- gsub("\u003D", "=>", x)
Я иногда использую конструкцию как
lapply(x, utf8ToInt)
чтобы увидеть, где верхние кодовые точки, например, больше 150. Это помогает мне находить проблемы, вызванные, например, неразрывными пробелами, которые, кажется, всплывают время от времени.
Хитрость в том, что '\\u003D'
на самом деле 6 символов, пока вы хотите '\u003D'
который является только одним персонажем. Дальнейшая хитрость заключается в том, что для соответствия этим обратным слешам вам нужно использовать дважды экранированные обратные слеши в шаблоне:
gsub("\\\\u003D\\\\u003E", "\u003D\u003E", x)
#[1] "pretty=>big"
Чтобы заменить несколько символов одним символом, вам нужно настроить таргетинг на весь шаблон. Вы не можете просто удалить обратную косую черту. (Поскольку вы указали, что это более общая проблема, я думаю, что ответ может заключаться в модификациях вашего пока не описанного способа загрузки этого текста.)
Когда я загружаю ваши функции и зависимости, этот код работает:
> freq <- ngram(c('pretty\u003D\u003Ebig'), year_start = 1950)
>
> str(freq)
'data.frame': 59 obs. of 4 variables:
$ Year : num 1950 1951 1952 1953 1954 ...
$ Phrase : Factor w/ 1 level "pretty=>big": 1 1 1 1 1 1 1 1 1 1 ...
$ Frequency: num 1.52e-10 6.03e-10 5.98e-10 8.27e-10 8.13e-10 ...
$ Corpus : Factor w/ 1 level "eng_2012": 1 1 1 1 1 1 1 1 1 1 ...
(Так что я думаю, что я до сих пор не понимаю, в каком случае.
> iconv('pretty\u003D\u003Ebig', "UTF-8", "ASCII")
[1] "pretty=>big"
но у вас, кажется, есть дополнительный побег