복붙노트

[RUBY-ON-RAILS] 어떻게 루비에서 라틴 문자 악센트 대체 할 수 있습니까?

RUBY-ON-RAILS

어떻게 루비에서 라틴 문자 악센트 대체 할 수 있습니까?

나는 이름 필드가있는 액티브 모델, 푸를 가지고있다. 나는 사용자 이름으로 검색 할 수 있도록하고 싶습니다,하지만 난 경우 및 악센트를 무시하도록 검색을하고 싶습니다. 따라서, 나는 또한 검색 할에 대한 canonical_name 필드를 저장하고 있습니다 :

class Foo
  validates_presence_of :name

  before_validate :set_canonical_name

  private

  def set_canonical_name
    self.canonical_name ||= canonicalize(self.name) if self.name
  end

  def canonicalize(x)
    x.downcase.  # something here
  end
end

나는 "여기서 뭔가"를 채우기 위해 악센트 문자를 교체해야합니다. 거기에 아무것도 더 나은보다

x.downcase.gsub(/[àáâãäå]/,'a').gsub(/æ/,'ae').gsub(/ç/, 'c').gsub(/[èéêë]/,'e')....

내가 루비 1.9에 대한 아니에요 그리고 이후, 그 문제에 관해서, 나는 내 코드에서 유니 코드 리터럴을 넣을 수 없습니다. 실제 정규 표현식은 훨씬 더 추악한을 찾을 것입니다.

해결법

  1. ==============================

    1.이미 정상화를위한 내장을 가지고 레일, 당신은이 같은 다른 문자 (예 : 악센트 표시)를 제거 한 후 KD를 형성하기 위해 문자열을 정상화하기 위해 이것을 사용하고 있습니다 :

    이미 정상화를위한 내장을 가지고 레일, 당신은이 같은 다른 문자 (예 : 악센트 표시)를 제거 한 후 KD를 형성하기 위해 문자열을 정상화하기 위해 이것을 사용하고 있습니다 :

    >> "àáâãäå".mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.to_s
    => "aaaaaa"
    
  2. ==============================

    2.ActiveSupport :: Inflector.transliterate는 (레일 2.2.1+과 루비 1.9 또는 1.8.7 필요)

    ActiveSupport :: Inflector.transliterate는 (레일 2.2.1+과 루비 1.9 또는 1.8.7 필요)

    예:

    >> ActiveSupport :: Inflector.transliterate ( "AAAAAA"). 그리고 to_s => "AAAAAA"

  3. ==============================

    3.더 나은 아직 국제화를 사용하는 것입니다 :

    더 나은 아직 국제화를 사용하는 것입니다 :

    1.9.3-p392 :001 > require "i18n"
     => false
    1.9.3-p392 :002 > I18n.transliterate("Olá Mundo!")
     => "Ola Mundo!"
    
  4. ==============================

    4.나는이 방법을 많이 시도하지만 그들은 이러한 요구 사항 중 하나 또는 몇 가지를 달성하지 않은 :

    나는이 방법을 많이 시도하지만 그들은 이러한 요구 사항 중 하나 또는 몇 가지를 달성하지 않은 :

    이되었습니다

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

    – http://blog.slashpoundbang.com/post/12938588984/remove-all-accents-and-diacritics-from-string-in-ruby

    당신은 조금 'N'문자를 존중하는 문자 목록을 비트 수정해야하지만 쉬운 일이다.

  5. ==============================

    5.내 대답 : 문자열 #의 파라미터 화 방법 :

    내 대답 : 문자열 #의 파라미터 화 방법 :

    "Le cœur de la crémiére".parameterize
    => "le-coeur-de-la-cremiere"
    

    위한 프로그램을 비 레일 :

    activesupport 설치 : 보석은 activesupport 설치 :

    require 'active_support/inflector'
    "a&]'s--3\014\xC2àáâã3D".parameterize
    # => "a-s-3-3d"
    
  6. ==============================

    6.난 당신이 어쩌면 정말 그 길을 어떻게 내려 가지 않도록 할 것이라고 생각합니다. 당신이 편지의이 종류가있는 시장을 개발하는 경우 사용자는 아마 당신의 ... 핍 일종의 생각합니다. 'A'는 근처에도 'A'어떤 의미에서 사용자가 아니기 때문에. 다른 길을 타고 ASCII 이외의 방법으로 검색에 대해 읽어. 이것은 단지 이러한 경우 누군가 발명 유니 코드 및 데이터 정렬 중 하나입니다.

    난 당신이 어쩌면 정말 그 길을 어떻게 내려 가지 않도록 할 것이라고 생각합니다. 당신이 편지의이 종류가있는 시장을 개발하는 경우 사용자는 아마 당신의 ... 핍 일종의 생각합니다. 'A'는 근처에도 'A'어떤 의미에서 사용자가 아니기 때문에. 다른 길을 타고 ASCII 이외의 방법으로 검색에 대해 읽어. 이것은 단지 이러한 경우 누군가 발명 유니 코드 및 데이터 정렬 중 하나입니다.

    아주 늦게 PS :

    http://www.w3.org/International/wiki/Case_folding http://www.w3.org/TR/charmod-norm/#sec-WhyNormalization

    게다가 나는 어떤 IDE 방식에게 MSDN 페이지 정렬 갈 수있는 링크가 없지만 내가 거기에두고있다. 그것은 http://www.unicode.org/reports/tr10/ 있었어야

  7. ==============================

    7.문자열을 분해하고 그것에서 간격이없는 표시를 제거합니다.

    문자열을 분해하고 그것에서 간격이없는 표시를 제거합니다.

    irb -ractive_support/all
    > "àáâãäå".mb_chars.normalize(:kd).gsub(/\p{Mn}/, '')
    aaaaaa
    

    .rb 파일에 사용되는 경우에도이 필요할 수 있습니다.

    # coding: utf-8
    

    평준화 (: KD : ()는 n이 불러 구별 틸다 문자 다음에 단일 문자 "틸다와 n은"분할 전) 및 GSUB 부분은 모두에게 구별자를 제거 부분이있어 구별하지 수를 나눈다.

  8. ==============================

    8.이것은 당신이 레일 사용하는 가정합니다.

    이것은 당신이 레일 사용하는 가정합니다.

    "anything".parameterize.underscore.humanize.downcase
    

    귀하의 요구 사항을 감안할 때, 이것이 내가 할 줄 것을 아마 ... 나는 깔끔한, 간단하고 레일과 루비의 향후 버전에서 최신 상태로 유지 것이라 생각합니다.

    업데이트 : 짧고 깨끗 : dgilperez는 매개 변수화는 ( "") .parameterize을 그래서, "아무것도"구분 인수를 취하는 "(".parameterize 구분을 ") 아무것도 (사용되지 않음) 또는"고 지적했다.

  9. ==============================

    9.정규화 양식 D에 텍스트를 변환 유니 코드 범주 이외의 간격 마크 (Mn)은 모든 코드 포인트를 제거하고 모든 분음 부호를 제거합니다 정규화 양식 C.이로 다시 변환하고, 문제는 대소 문자를 구분 검색으로 감소된다.

    정규화 양식 D에 텍스트를 변환 유니 코드 범주 이외의 간격 마크 (Mn)은 모든 코드 포인트를 제거하고 모든 분음 부호를 제거합니다 정규화 양식 C.이로 다시 변환하고, 문제는 대소 문자를 구분 검색으로 감소된다.

    자세한 내용은 http://www.siao2.com/2005/02/19/376617.aspx 및 http://www.siao2.com/2007/05/14/2629747.aspx를 참조하십시오.

  10. ==============================

    10.canonical_text 및 original_text : 키는 데이터베이스에 두 개의 열을 사용하는 것입니다. 검색을위한 디스플레이와 canonical_text에 대한 original_text 사용합니다. 그런 식으로, 대한 사용자 검색 "비주얼 카페는,"그녀는 "비주얼 카페"결과를보고합니다. 그녀는 정말 ", 비주얼 카페"라는 다른 항목을 원하는 경우 별도로 저장할 수 있습니다.

    canonical_text 및 original_text : 키는 데이터베이스에 두 개의 열을 사용하는 것입니다. 검색을위한 디스플레이와 canonical_text에 대한 original_text 사용합니다. 그런 식으로, 대한 사용자 검색 "비주얼 카페는,"그녀는 "비주얼 카페"결과를보고합니다. 그녀는 정말 ", 비주얼 카페"라는 다른 항목을 원하는 경우 별도로 저장할 수 있습니다.

    같은 것을 할, 루비 1.8 소스 파일의 canonical_text 문자를 얻으려면 :

    register_replacement([0x008A].pack('U'), 'S')
    
  11. ==============================

    11.당신은 아마 유니 코드 분해 ( "NFD")을 할 수 있습니다. 문자열을 분해 한 후,이 [A-ZA-Z]에없는 것을 걸러. (- 분음는 별도의 문자가 될 것이다 약)를 필터링 잎 그래서 합리적인 근사치 æ "는 ~"에 "AE"A를 분해합니다.

    당신은 아마 유니 코드 분해 ( "NFD")을 할 수 있습니다. 문자열을 분해 한 후,이 [A-ZA-Z]에없는 것을 걸러. (- 분음는 별도의 문자가 될 것이다 약)를 필터링 잎 그래서 합리적인 근사치 æ "는 ~"에 "AE"A를 분해합니다.

  12. ==============================

    12.의 iconv :

    의 iconv :

    http://groups.google.com/group/ruby-talk-google/browse_frm/thread/8064dcac15d688ce?

    =============

    내가 이해할 수없는 펄 모듈 :

    http://www.ahinea.com/en/tech/accented-translate.html

    ============

    브 루트 포스 (그 동물이 많이있다! :

    http://projects.jkraemer.net/acts_as_ferret/wiki#UTF-8support

    http://snippets.dzone.com/posts/show/2384

  13. ==============================

    13.사람이이 유용 할 수있는 모든 비 ASCII 문자를 제거하고자 읽기 위해, 나는 성공적으로 첫 번째 예제를 사용했다.

    사람이이 유용 할 수있는 모든 비 ASCII 문자를 제거하고자 읽기 위해, 나는 성공적으로 첫 번째 예제를 사용했다.

  14. ==============================

    14.(: KD) .gsub 일에 (/ [^ \ x00- \ x7F] / N, '') downcase.to_s 솔루션입니다. 나는 데 문제가 foo.mb_chars.normalize를 받고 있었다. 나는 레일을 사용하지 않는 내가의 바닥에 얻을 수 없다는 것을 내 activesupport / 루비 버전과 약간의 충돌이 있었다.

    (: KD) .gsub 일에 (/ [^ \ x00- \ x7F] / N, '') downcase.to_s 솔루션입니다. 나는 데 문제가 foo.mb_chars.normalize를 받고 있었다. 나는 레일을 사용하지 않는 내가의 바닥에 얻을 수 없다는 것을 내 activesupport / 루비 버전과 약간의 충돌이 있었다.

    루비-UNF 보석을 사용하여 좋은 대용품이 될 것 같다 :

    require 'unf'
    foo.to_nfd.gsub(/[^\x00-\x7F]/n,'').downcase
    

    (: KD) 지금까지 내가 말할 수있는이 .mb_chars.normalize과 같은 일을한다. 이 올바른지? 감사!

  15. ==============================

    15.당신이 당신의 DB 어댑터로 PostgreSQL을 => 9.4을 사용하는 경우, 아마 당신은 이전에 당신이 이런 식으로, 원하는 것을 생각하는 그것의 "unaccent"확장자를 추가 할 수 있습니다 :

    당신이 당신의 DB 어댑터로 PostgreSQL을 => 9.4을 사용하는 경우, 아마 당신은 이전에 당신이 이런 식으로, 원하는 것을 생각하는 그것의 "unaccent"확장자를 추가 할 수 있습니다 :

    def self.up
       enable_extension "unaccent" # No falla si ya existe
    end
    

    테스트하기 위해, 콘솔에서 :

    2.3.1 :045 > ActiveRecord::Base.connection.execute("SELECT unaccent('unaccent', 'àáâãäåÁÄ')").first
     => {"unaccent"=>"aaaaaaAA"}
    

    공지 사항 지금에 대소 문자를 구분까지있다.

    그런 다음, 어쩌면 같은 범위에서 사용 :

    scope :with_canonical_name, -> (name) {
       where("unaccent(foos.name) iLIKE unaccent('#{name}')")
    }
    

    아이 라이크 연산자는 검색 케이스를 구분한다. 또 다른 방법은 citext 데이터 유형을 사용하여 있습니다. 다음은이 두 가지 접근 방식에 대한 논의이다. 공지 사항은 PosgreSQL의 낮은 () 함수의 사용은 권장되지 않았는지 확인합니다.

    이것은 당신이 더 이상 cannonical_name 필드를 필요로하지 않으므로, 몇 가지 DB 공간을 절약하고, 아마도 모델 간단하게, 각 쿼리에 몇 가지 추가 처리 비용으로, 양으로 당신이 아이 라이크 또는 citext 사용 여부의 따라 것 데이터 집합.

    당신이 MySQL을 사용하는 경우 어쩌면 당신은이 간단한 솔루션을 사용할 수 있습니다,하지만 난 그것을 테스트하지 않았습니다.

  16. ==============================

    16.LOL .. 난 그냥이 시도 .. 그리고 그것은 노력하고 있습니다 .. 메신저 아직도 확신하는 이유 ..하지만 내가 코드의 4 개 라인을 사용하는 경우 :

    LOL .. 난 그냥이 시도 .. 그리고 그것은 노력하고 있습니다 .. 메신저 아직도 확신하는 이유 ..하지만 내가 코드의 4 개 라인을 사용하는 경우 :

    자동 내가 제거하려는 (파일 이름에서 악센트와보다 그 이름을 변경) 된 파일 이름 ..이 :) 도움이 희망에서 어떤 악센트를 제거

  17. from https://stackoverflow.com/questions/225471/how-do-i-replace-accented-latin-characters-in-ruby by cc-by-sa and MIT license