Преобразовать строку полной ширины в строку половинной ширины с помощью r
Как я могу конвертировать Ab9876543210
в Ab9876543210
? Есть ли решение по регулярному выражению? Благодарю.
test <- dput("Ab9876543210")
2 ответа
Отказ от ответственности: на моем компьютере работает следующее, но, поскольку я не могу воспроизвести вашу строку полной ширины, основываясь исключительно на представленном примере, это лучшее предположение, основанное на моей версии проблемы (вставка строки в текстовый файл, сохранение ее с кодировкой UTF-8 и загружая его с кодировкой, указанной как UTF-8.
Шаг 1 Чтение в тексте (я добавил для сравнения версию половинной ширины):
> test <- readLines("fullwidth.txt", encoding = "UTF-8")
> test
[1] "Ab9876543210" "Ab9876543210"
Шаг 2 Убедиться, что версии full & half width не равны:
# using all.equal()
test1 <- test[1]
test2 <- test[2]
> all.equal(test1, test2)
[1] "1 string mismatch"
# compare raw bytes
> charToRaw(test1)
[1] ef bb bf ef bc a1 62 ef bc 99 ef bc 98 ef bc 97 ef bc 96 ef bc 95 ef
[24] bc 94 ef bc 93 ef bc 92 ef bc 91 ef bc 90
> charToRaw(test2)
[1] 41 62 39 38 37 36 35 34 33 32 31 30
Для всех, кто заинтересован, если вы вставите необработанную байтовую версию в декодер utf-8 в качестве шестнадцатеричного ввода, вы увидите, что за исключением буквы b (сопоставленной с 62 в 7-м байте), остальные буквы были сформированы из 3- последовательности байтов. Кроме того, первая 3-байтовая последовательность отображается на символ "ZERO WIDTH NO-BREAK SPACE", поэтому она не отображается при печати строки в консоли.
Шаг 3 Преобразование из полной ширины в половину ширины с помощью Nippon
пакет:
library(Nippon)
test1.converted <- zen2han(test1)
> test1.converted
[1] "Ab9876543210"
# If you want to compare against the original test2 string, remove the zero
# width character in front
> all.equal(substring(test1.converted, 2), test2)
[1] TRUE
С опозданием на несколько лет, но вот базовое решение R
Символы полной ширины находятся в диапазоне
0xFF01:0xFFEF
, и может быть смещено следующим образом.
x <- "Ab9876543210"
iconv(x, to = "utf8") |>
utf8ToInt() |>
(\(.) ifelse(. > 0xFF01 & . <= 0xFFEF, . - 65248, .))() |>
intToUtf8()
[1] "Ab9876543210"