Ruby正则表达式捕获gsub中的组

时间:2016-05-24 20:36:33

标签: ruby regex gsub

假设我想切换消息中的每个字母,并将其放在反向字母表中。为什么我似乎无法使用捕获的组并在一个gsub中执行此操作?

也许有人可以解释一下在gsub中使用捕获的组,后面的引用是否可以裸(没有'')?我可以使用#{\ 1}吗?

def decode(message)
  a = ('a'..'z').to_a
  z = a.reverse
  message.gsub!(/([[:alpha:]])/, z[a.index('\1')]) 
end

decode("the quick brown fox")

3 个答案:

答案 0 :(得分:7)

请记住,方法的参数会立即进行评估,并将结果传递给方法。如果你想让替换适应匹配:

message.gsub!(/([[:alpha:]])/) { |m| z[a.index($1)] }

使用一个块来评估每场比赛。

答案 1 :(得分:2)

使用gsub

您的代码无效,因为'\1'尚未被评估为正则表达式匹配,在您需要的时候。这可以通过使用块来解决,因此定义了匹配变量:

message.gsub(/[[:alpha:]]/) { |char| z[a.index(char)] }

使用tr

一种更有效的解决此类问题的方法,就是使用String#tr来简单地“将一组字符替换为另一组字符”。这可以按如下方式完成:

message.tr(a.join(''), z.join(''))

答案 2 :(得分:0)

一种方法是操纵ASCII值。

def code(message)
  message.gsub(/[[:alpha:]]/) { |s| (((s < 'a') ? 155 : 219 ) - s.ord).chr }
end

coded = code("the quick brown fox")
  #=> "gsv jfrxp yildm ulc" 
code(coded)
  #=> "the quick brown fox" 

注意:

'A'.ord + 'Z'.ord
  #=> 155 
'a'.ord + 'z'.ord
  #=> 219 

另一种方法是使用哈希:

a = ('a'..'z').to_a
Ch = a.zip(a.reverse).to_h
  #=> {"a"=>"z", "b"=>"y",..., "y"=>"b", "z"=>"a"} 

def code(message)
  message.gsub(/[[:alpha:]]/, Ch)
end

coded = code("the quick brown fox")
  #=> "gsv jfrxp yildm ulc"
code(coded)
  #=> "the quick brown fox"