如何使用Ruby中的RegEx更改字符串中的字母大小写
说我有一个字符串:“hEY”
我想将它转换为“嘿”
string.gsub!(/([az])([AZ]+ )/, '\1'.upcase)
这就是我的想法,但是当我在gsub方法中使用它时,似乎upcase方法什么都不做。 这是为什么?
编辑:我想出了这个方法:
string.gsub!(/([az])([AZ]+ )/) { |str| str.downcase!.capitalize! }
有没有办法在正则表达式中执行此操作? 我真的不明白’\ 1”\ 2’的事情。 这是反向引用吗? 这是如何运作的
@sawa有简单的答案,你用其他机制编辑了你的问题。 但是,回答你的两个问题:
有没有办法在正则表达式中执行此操作?
不,Ruby的正则表达式不像其他一些正则表达式那样支持改变大小写的function。 您可以通过查看1.9和2.0的官方Ruby正则表达式文档并搜索“case”一词来“certificate”这一点:
- https://github.com/ruby/ruby/blob/ruby_1_9_3/doc/re.rdoc
- https://github.com/ruby/ruby/blob/ruby_2_0_0/doc/re.rdoc
我真的不明白’\ 1”\ 2’的事情。 这是反向引用吗? 这是如何运作的?
你对\1
使用是一种反向引用。 反向引用可以是在搜索模式中使用\1
等。 例如,正则表达式/f(.)\1/
将找到字母f
,后跟任何字符,后跟相同的字符(例如“foo”或“f !!”)。
在这种情况下,在传递给String#gsub
类的方法的替换字符串中,反向引用确实引用了先前的捕获。 来自文档:
“如果替换是一个字符串,它将替换匹配的文本。它可能包含对格式
\d
的模式捕获组的反向引用,其中d
是一个组号,或者\k
,其中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!(/([az])([AZ]+ )/, '\1'.upcase)
…你正在做的是在字符串'\1'
上调用upcase
(没有效果), 然后调用gsub!
方法,传入正则表达式和字符串作为参数。
最后,实现同一目标的另一种方法是使用块forms,如下所示:
# Take your pick of which you prefer: string.gsub!(/([az])([AZ]+ )/){ $1.upcase << $2.downcase } string.gsub!(/([az])([AZ]+ )/){ [$1.upcase,$2.downcase].join } string.gsub!(/([az])([AZ]+ )/){ "#{$1.upcase}#{$2.downcase}" }
在gsub的块forms中,捕获的模式被设置为全局变量$1
, $2
等,您可以使用它们来构造替换字符串。
我不知道你为什么要以复杂的方式去做,但通常的方法是:
"hEY".capitalize # => "Hey"
如果你坚持使用正则表达式和upcase
,那么你还需要downcase
:
"hEY".downcase.sub(/\w/){$&.upcase} # => "Hey"
如果你真的只想交换字符串中每个字母的大小写,你可以完全避免正则表达式的复杂性,因为有一个方法For That That。
"hEY".swapcase # => "Hey" "HellO thERe".swapcase # => "hELLo THerE"
还有swapcase!
破坏性地去做。