【问题标题】:Why doesn't this Unicode gsub substitution work in Ruby?为什么这个 Unicode gsub 替换在 Ruby 中不起作用?
【发布时间】:2012-12-26 14:11:31
【问题描述】:

another question 中,有人询问如何替换变音符号。接受的问题是以下代码:

# encoding: utf-8
foo = "ich bin doch nicht blöd, mann!".gsub(/[äöü]/) do |match|
    case match
        when "ä" 'ae'
        when "ö" 'oe'
        when "ü" 'ue'
    end
end
puts foo

但是,当我尝试运行它时,输出是:

$ ruby /tmp/test.rb 
ich bin doch nicht bld, mann!

所以元音变音显然不会被替换。 我有什么遗漏吗?我使用的是 Ruby 1.9.3p362(2012-12-25 修订版 38607)[x86_64-linux]

【问题讨论】:

    标签: ruby unicode


    【解决方案1】:

    您使用的语法不正确,您需要使用then 或换行符和缩进。

    # encoding: utf-8
    foo = "ich bin doch nicht blöd, mann!".gsub(/[äöü]/) do |match|
        case match
            when "ä" then 'ae'
            when "ö" then 'oe'
            when "ü" then 'ue'
        end
    end
    
    puts foo
    

    # encoding: utf-8
    foo = "ich bin doch nicht blöd, mann!".gsub(/[äöü]/) do |match|
        case match
            when "ä"
                "ae"
            when "ö"
                "oe"
            when "ü"
                "ue"
        end
    end
    

    执行此操作的可靠方法是 result = Iconv.iconv('ascii//ignore//translit', 'utf-8', foo),但您需要将语言环境设置为 "de_DE",这在没有 c 扩展名的情况下无法在 ruby​​ 中完成。

    【讨论】:

    • 它有趣的 ruby​​ 不会因为缺少 then 语句而发出警告! +1
    • @cggaurav 通常省略then 会是语法错误,但将两个字符串文字并排写实际上在语法上是有效的。写"ä" 'ae' 和写"äae" 是一样的。这是 Ruby 继承自 C 的语法上的奇怪之处。
    • 我在 Ruby 核心开发者网站上阅读了关于在两个文字位于同一行时弃用此功能的讨论。似乎是没有用的共识。
    【解决方案2】:
    "ich bin doch nicht blöd, mann!".gsub("ä","ae").gsub("ö","oe").gsub("ü","ue")
    

    应该做的伎俩

    【讨论】:

    • 这很快而且有效。谢谢!知道为什么其他代码不起作用吗? (我会在 10 分钟内接受你的回答,因为这是接受前的最短等待时间)
    • 这会很快变得丑陋(想想 Ä、ä、Ö、ö、Ü、ü 和 ß;é è 等)
    【解决方案3】:

    (不是问题的真正答案,但评论有点大。)gsub 具有这种替换的语法,使用哈希:

    #encoding: utf-8
    table = {"ä" => 'ae',
             "ö" => 'oe',
             "ü" => 'ue'}
    re = Regexp.union(table.keys)
    # re = /[äöü]/ # is fine too
    p "ich bin doch nicht blöd, mann!".gsub(re, table)
    # => "ich bin doch nicht bloed, mann!"
    

    【讨论】:

    • 我最近三次看到这个。你两次,我一次。
    • 我有一个秘密议程 :),我希望 Regexp.union 是自动的,保留语法 gsub(hash)。但该功能目前并不为人所知。
    • 我同意。我也有同样的感觉。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多