2013-03-28 3 views
42

Я пытаюсь создать «нормализованную» копию строки, чтобы уменьшить дублирующиеся имена в базе данных. Имена содержат много международных символов (например, букв с акцентом), и я хочу создать копию с удаленными акцентами.Метод Ruby для удаления акцентов из международных символов UTF-8

Я натолкнулся на приведенный ниже метод, но не могу заставить его работать. Я не могу найти, что такое плагин Unicode Hacks.

# Utility method that retursn an ASCIIfied, downcased, and sanitized string. 
    # It relies on the Unicode Hacks plugin by means of String#chars. We assume 
    # $KCODE is 'u' in environment.rb. By now we support a wide range of latin 
    # accented letters, based on the Unicode Character Palette bundled inMacs. 
    def self.normalize(str) 
    n = str.chars.downcase.strip.to_s 
    n.gsub!(/[à áâãäåÄÄ?]/u, 'a') 
    n.gsub!(/æ/u,     'ae') 
    n.gsub!(/[ÄÄ?]/u,    'd') 
    n.gsub!(/[çÄ?ÄÄ?Ä?]/u,   'c') 
    n.gsub!(/[èéêëÄ?Ä?Ä?Ä?Ä?]/u, 'e') 
    n.gsub!(/Æ?/u,     'f') 
    n.gsub!(/[ÄÄ?Ä¡Ä£]/u,   'g') 
    n.gsub!(/[ĥħ]/,    'h') 
    n.gsub!(/[ììíîïīĩĭ]/u,  'i') 
    n.gsub!(/[įıijĵ]/u,   'j') 
    n.gsub!(/[ķĸ]/u,    'k') 
    n.gsub!(/[Å?ľĺļÅ?]/u,   'l') 
    n.gsub!(/[ñÅ?Å?Å?Å?Å?]/u,  'n') 
    n.gsub!(/[òóôõöøÅÅ?ÅÅ]/u, 'o') 
    n.gsub!(/Å?/u,     'oe') 
    n.gsub!(/Ä?/u,     'q') 
    n.gsub!(/[Å?Å?Å?]/u,    'r') 
    n.gsub!(/[Å?Å¡Å?ÅÈ?]/u,   's') 
    n.gsub!(/[ťţŧÈ?]/u,   't') 
    n.gsub!(/[ùúûüūůűŭũų]/u,'u') 
    n.gsub!(/ŵ/u,     'w') 
    n.gsub!(/[ýÿŷ]/u,    'y') 
    n.gsub!(/[žżź]/u,    'z') 
    n.gsub!(/\s+/,     ' ') 
    n.gsub!(/[^\sa-z0-9_-]/,   '') 
    n 
    end 

Нужно ли «требовать» конкретную библиотеку/драгоценный камень? Или, может быть, кто-то может порекомендовать другой способ этого.

Я не пользуюсь Rails и не планирую делать это.

+1

Какой версией рубина вы используете? – Huluk

+0

Взгляните на http://stackoverflow.com/questions/1268289/how-to-get-rid-of-non-ascii-characters-in-ruby – MurifoX

+3

, вы также можете посмотреть: https://github.com/norman/unidecoder –

ответ

148

Я обычно использую I18n, чтобы справиться с этим:

1.9.3p392 :001 > require "i18n" 
=> true 
1.9.3p392 :002 > I18n.transliterate("Hé les mecs!") 
=> "He les mecs!" 
+3

[Документация] (http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method -i-Transliterate). Способность устанавливать транслитерации на основе каждой локали также очень эффективна. –

+0

Кажется, это то, что я ищу. Благодарю. –

+2

Прямо под моим носом. Спасибо! – Trip

8

До сих пор следующий единственный способ, которым я был в состоянии сделать то, что мне нужно:

str.tr(
"ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž", 
"AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz") 

Но с помощью этого чувствует себя очень «хак», и я хотел бы, чтобы найти лучший путь.

+1

Это работает только для ISO-8859-1. Что заставляет вас думать, что это работает для UTF-8? – pts

+0

Это работает для UTF-8 и ruby ​​2.2.3 и делает именно то, что мне нужно. Однако не хватает румынских персонажей. Я aded их: 'string.tr ( "ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšŞşsŢţŤťŦŧŢţÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž", "AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSsSssTtTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz")' – Alexander

Смежные вопросы