stri_unescape_unicode () не работает на некоторых символах - PullRequest
0 голосов
/ 07 июня 2018

У меня проблема с преобразованием символов Юникода в R. Я придерживаюсь этого подхода, но stri_unescape_unicode из библиотеки stringi не может вернуть правильное значение в некоторых случаях.Позвольте мне показать пример, где правильным значением должно быть слово Tomáš :

library(stringi)
test <- "Tom<U+00E1><U+009A>"
test <- gsub("<U\\+(....)>", "\\\\u\\1", test)
stri_unescape_unicode(test)
[1] "Tomá\u009a"

Однако, если š представлено U + 0161 вместо U + 009A , все работает как ожидалось:

test2 <- "Tom<U+00E1><U+0161>"
test2 <- gsub("<U\\+(....)>", "\\\\u\\1", test2)
stri_unescape_unicode(test2)
[1] "Tomáš"

Теперь моя проблема в том, что у меня большой character вектор с многочисленными элементами, такими как test и stri_unescape_unicode не подходит для некоторых символов, таких как <U+009A> здесь.Мой вопрос:

  • Есть ли способ конвертировать <U+009A> с помощью stri_unescape_unicode или любым другим способом?
  • В качестве альтернативы, есть ли способ автоматической замены юникодов в случае stri_unescape_unicode не удается?То есть в моем примере "Tom<U+00E1><U+009A>" должно стать "Tom<U+00E1><U+0161>"?

1 Ответ

0 голосов
/ 20 декабря 2018

Похоже, что stri_unescape_unicode() не удалось.Символ был преобразован, но он является управляющим символом («односимвольный вводчик» U + 009A) и печатается с использованием его кода.Мусор входит, мусор выходит.

Как R печатает строки Unicode, зависит от типа консоли и используемой локали.Следующий пример был запущен через пакет reprex с использованием кодовой страницы 1252 в Windows.Даже если непечатаемый символ печатается в стиле <U+> или \u, фактический символ Unicode существует в соответствующей строке R.

library(stringi)
test2 <- c("Tom<U+00E1><U+009A>", "Tom<U+00E1><U+0161>")
test2 <- gsub("<U\\+(....)>", "\\\\u\\1", test2)
unesc2 <- stri_unescape_unicode(test2)
unesc2
#> [1] "Tomá<U+009A>" "Tomáš"
nchar(unesc2)
#> [1] 5 5
cap2 <- capture.output(cat(unesc2, sep = "\n"))
cap2
#> [1] "Tomá<U+009A>" "Tomáš"
nchar(cap2)
#> [1] 12  5
which(nchar(cap2) > nchar(unesc2))
#> [1] 1
es2 <- encodeString(unesc2)
es2
#> [1] "Tomá\\u009a" "Tomáš"
nchar(es2)
#> [1] 10  5
which(nchar(es2) > nchar(unesc2))
#> [1] 1

Я думаю, capture.output() или encodeString() в сочетании сnchar() можно использовать, как указано выше, для обнаружения строк с плохими, то есть непечатаемыми в текущей локали символами.Затем, если кажется, что все случаи U + 009A должны быть на самом деле U + 0161, исправить это - простая задача для gsub(), например, gsub("\u009a", "\u0161", unesc2) и т. Д.

...