Ошибка замены кодировки Ruby - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь прочитать текстовый файл, который содержит много строк с акцентами (пунктуация), и заполнить базу данных этими строками без этих акцентов, используя Ruby (не On Rails).

Например, у меня есть:

J'ai été mise au courant des éventualités à temps.

Я хочу заменить всю строку на следующую строку:

J'ai ete mise au courant des eventualites temps.

Итак, для этого я нашел тот метод, который должен работать:

    def convert_to_ascii(s)
        undefined = ''
        fallback = { 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A',
                   'Å'=>'A', 'Æ'=>'AE', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
                   'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I',
                   'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
                   'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U',
                   'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'à'=>'a', 'á'=>'a',
                   'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'ae',
                   'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e',
                   'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ñ'=>'n',
                   'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o',
                   'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'u',
                   'ý'=>'y', 'ÿ'=>'y' }

        s.encode('ASCII',fallback: lambda { |c| fallback.key?(c) ? fallback[c] : undefined })
   end

Но он просто даетмне следующую строку:

J'ai t mise au courant des ventualits temps.

Или даже:

J'ai �tise mise au courant des �ventualit's temps.

Я не понимаю, почему это не работает ...

РЕДАКТИРОВАТЬ:

Я использовал

file = File.open(i_FileName, 'r:utf-8')

Чтобы прочитать файл, я заменил его на

file = File.open(i_FileName, 'r:iso-8859-1:utf-8')

И он работает как шарм!

1 Ответ

0 голосов
/ 26 апреля 2018

TL; DR: Использование String#unicode_normalize.

Неожиданный результат вызван тем, что может быть 1 символом (так называемый состав Unicodeформа), а также 2 (два) различных символа (разложенная форма Unicode.)

"J'ai été mise au courant des éventualités à temps.".
  unicode_normalize(:nfd).
  gsub(/./) { |m| m.ord > 255 ? '' : m }
#⇒ "J'ai ete mise au courant des eventualites a temps."

Или, что еще проще:

"J'ai été mise au courant des éventualités à temps.".
  unicode_normalize(:nfd).gsub(/[\u0300-\u036F]/, '')
#⇒ "J'ai ete mise au courant des eventualites a temps."

То, что мы делаем здесь: мы нормализуемСтрока в разложенную форму (все объединенные диакритические знаки становятся отдельными символами .) Затем мы сбриваем их с String#gsub.


Если вы чувствуете жалость квыбросить существующий код, нормализовать строку в составленную форму и использовать вашу encode, теперь она будет работать.

composed = "J'ai été mise au courant des éventualités à temps.".
   unicode_normalize(:nfc) # NOTE :nfc parameter

composed.encode(.....)
...