【问题标题】:How to change case of letters in string using RegEx in Ruby如何在 Ruby 中使用 RegEx 更改字符串中字母的大小写
【发布时间】:2013-03-26 16:04:54
【问题描述】:

假设我有一个字符串:“hEY”

我想把它转换成“嘿”

string.gsub!(/([a-z])([A-Z]+ )/, '\1'.upcase)

这就是我的想法,但是当我在 gsub 方法中使用 upcase 方法时,它似乎什么也没做。这是为什么呢?

编辑:我想出了这个方法:

string.gsub!(/([a-z])([A-Z]+ )/) { |str| str.downcase!.capitalize! }

有没有办法在正则表达式中做到这一点?我真的不明白 '\1' '\2' 的事情。那是反向引用吗?它是如何工作的

【问题讨论】:

    标签: ruby regex


    【解决方案1】:

    @sawa 有简单的答案,并且您已经使用另一种机制编辑了您的问题。但是,要回答您的两个问题:

    有没有办法在正则表达式中做到这一点?

    不,Ruby 的正则表达式不支持 some other regex flavors do 那样的大小写更改功能。您可以通过查看 1.9 和 2.0 的官方 Ruby 正则表达式文档并搜索“case”一词来“证明”这一点:

    我不太明白 '\1' '\2' 的意思。那是反向引用吗?它是如何工作的?

    您对\1 的使用是一种反向引用。当您在搜索模式中使用 \1 等时,可能会出现反向引用。例如,正则表达式/f(.)\1/ 会找到字母f,后跟任意字符,再后跟相同的字符(例如“foo”或“f!!”)。

    在这种情况下,在传递给String#gsub 之类的方法的替换字符串中,反向引用确实引用了先前的捕获。来自文档:

    "如果替换是一个字符串,它将被匹配的文本替换。它可能包含对\d形式的模式捕获组的反向引用,其中d是一个组号,或者\k<n>,其中n 是组名。如果它是双引号字符串,则两个反向引用必须在前面加上一个额外的反斜杠。"

    实际上,这意味着:

    "hello world".gsub( /([aeiou])/, '_\1_' )  #=> "h_e_ll_o_ w_o_rld"
    "hello world".gsub( /([aeiou])/, "_\1_" )  #=> "h_\u0001_ll_\u0001_ w_\u0001_rld"
    "hello world".gsub( /([aeiou])/, "_\\1_" ) #=> "h_e_ll_o_ w_o_rld"
    

    现在,您必须了解代码何时运行。在您的原始代码中……

    string.gsub!(/([a-z])([A-Z]+ )/, '\1'.upcase)
    

    ...您正在做的是在字符串'\1' 上调用upcase(没有效果)然后然后调用gsub! 方法,传入一个正则表达式和一个字符串作为参数.

    最后,实现相同目标的另一种方法是使用块形式,如下所示:

    # Take your pick of which you prefer:
    string.gsub!(/([a-z])([A-Z]+ )/){ $1.upcase << $2.downcase }
    string.gsub!(/([a-z])([A-Z]+ )/){ [$1.upcase,$2.downcase].join }
    string.gsub!(/([a-z])([A-Z]+ )/){ "#{$1.upcase}#{$2.downcase}" }
    

    在 gsub 的块形式中,捕获的模式被设置为全局变量 $1$2 等,您可以使用它们来构造替换字符串。

    【讨论】:

    • 所以美元符号是您在块表单中反向引用的方式?
    • @普通的排序。在进行任何正则表达式匹配后,Ruby 会更新全局变量 $1 等。除了其他位置之外,它们恰好以块形式提供。
    【解决方案2】:

    我不知道您为什么要尝试以复杂的方式进行操作,但通常的方式是:

    "hEY".capitalize # => "Hey"
    

    如果你坚持使用正则表达式和upcase,那么你还需要downcase

    "hEY".downcase.sub(/\w/){$&.upcase} # => "Hey"
    

    【讨论】:

      【解决方案3】:

      如果您真的只想交换字符串中每个字母的大小写,则可以完全避免正则表达式的复杂性,因为 There's A Method For That™。

      "hEY".swapcase # => "Hey"
      "HellO thERe".swapcase # => "hELLo THerE"
      

      还有 swapcase! 破坏性地这样做。

      【讨论】:

        猜你喜欢
        • 2011-05-12
        • 2020-02-15
        • 1970-01-01
        • 1970-01-01
        • 2012-01-03
        • 2019-06-08
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        相关资源
        最近更新 更多