Ruby-Methode zum Entfernen von Akzenten aus internationalen UTF-8-Zeichen


73

Ich versuche, eine "normalisierte" Kopie einer Zeichenfolge zu erstellen, um doppelte Namen in einer Datenbank zu reduzieren. Die Namen enthalten viele internationale Zeichen (z. B. Buchstaben mit Akzent), und ich möchte eine Kopie erstellen, bei der die Akzente entfernt sind.

Ich bin auf die folgende Methode gestoßen, kann sie aber nicht zum Laufen bringen. Ich kann anscheinend nicht finden, was das Unicode Hacks-Plugin ist.

  # 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

Muss ich eine bestimmte Bibliothek / ein bestimmtes Juwel "benötigen"? Oder vielleicht könnte jemand einen anderen Weg empfehlen, um dies zu erreichen.

Ich benutze weder Rails noch habe ich vor, dies zu tun.


1
Welche Ruby-Version verwenden Sie?
Huluk


3
Sie könnten auch schauen auf: github.com/norman/unidecoder
amalrik maia

Ich verwende Ruby 1.9.3. Ich werde mir beide möglichen Lösungen ansehen. Alles, was ich brauche, ist das Ersetzen der aufgelisteten Zeichen durch die oben beschriebene Methode. Wenn diese Lösungen das also großartig können und danke :)
Gus Shortz

Ich habe endlich einige Verweise auf das Unicode-Hack-Plugin ( railslodge.com/plugins/316-unicode-hacks ) gefunden, das die charsfür die von normalizemir erwähnte Methode erforderliche Methode bereitstellt . Aber es scheint nicht mehr unterstützt zu werden
Gus Shortz

Antworten:


217

Ich benutze normalerweise I18n, um damit umzugehen:

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

3
Die Dokumentation . Die Möglichkeit, Transliterationen pro Gebietsschema festzulegen, ist ebenfalls sehr leistungsfähig.
Paul Fioravanti

9
Dies funktioniert möglicherweise nicht so, wie Sie es von Zeichen erwarten, die keine grundlegenden lateinischen Zuordnungen haben - zum Beispiel chinesische Zeichen. Es macht sie nur zu Fragezeichen. (main)> I18n.transliterate("雙屬性集合之空間分群演算法-應用於地理資料") => "?????????????-???????"
David

15
Nur eine Notiz für einfachen Rubin, wenn sie I18n::InvalidLocale: :en is not a valid localegeworfen wird, I18n.available_locales = [:en]vorher verwendenI18n.transliterate
Alter Lagos

Hinweis: Dies funktioniert nicht für alle. Beispiel "Bùi Viện" wird übersetzt in "Bui Vi? N"
CHawk

2
Hat bei mir nicht funktioniert:(main)> I18n.transliterate "ŠKODA" => "ŠKODA"
Michael

18

Bisher konnte ich nur das erreichen, was ich brauche:

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

Aber dies zu benutzen fühlt sich sehr "hackisch" an und ich würde gerne einen besseren Weg finden.


1
Dies funktioniert nur für ISO-8859-1. Was lässt Sie denken, dass es für UTF-8 funktioniert?
Punkte

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

16

Die Parametrisierungsmethode könnte eine nette und einfache Lösung sein, um Sonderzeichen zu entfernen, um die Zeichenfolge als lesbare Kennung zu verwenden:

> "Françoise Isaïe".parameterize
=> "francoise-isaie"

Sie benutzen jedoch keine Schienen.
Schneeangel

2

Wenn Sie Schienen verwenden,

my_string = "L'Oréal"
my_string.parameterize(separator=' ')
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.