使用gsub和regex替换所有其他出现的字符

时间:2019-02-11 20:26:31

标签: regex ruby gsub

我正在设计纸牌游戏(黑桃)。我想将每手存储为哈希。

这是一个随机生成的字符串,代表一个人有13张卡,其中10c是密钥,10是值

"10c 10 bj 18 2s 15 3s 3 8d 8 as 14 kh 13 8c 8 3c 3 6d 6 kc 13 5d 5 ad 14"

我想用' '替换10c10之间的空格=>,并用10bj之间的空格替换逗号...应该像10c=>10,bj=>18

从那里,我将通过调用Hash#inspect将其转换为哈希值;但是,我找不到使用gsub替换字符串的第n个字符的方法。

我尝试调用hand.gsub(' ', '=>'),但这显然用=>替换了空格的每个实例

2 个答案:

答案 0 :(得分:2)

您可以立即使用

构建哈希
s = "10c 10 bj 18 2s 15 3s 3 8d 8 as 14 kh 13 8c 8 3c 3 6d 6 kc 13 5d 5 ad 14"
hash = Hash[s.scan(/(\w+) (\d+)/)].transform_values(&:to_i)

或者,对于旧版Ruby:

hash = Hash[s.scan(/(\w+) (\d+)/)]
hash = Hash[ hash.map{ |a, b| [ a, b.to_i ] } ]
puts hash
# => {"10c"=>10, "bj"=>18, "2s"=>15, "3s"=>3, "8d"=>8, "as"=>14, "kh"=>13, "8c"=>8, "3c"=>3, "6d"=>6, "kc"=>13, "5d"=>5, "ad"=>14}

请参见Ruby demo

(\w+) (\d+)模式将任何一个或多个单词字符(带有(\w+),字母,数字或下划线的字符匹配并捕获到组1中,您可以使用[[:alnum:]]+或{{1} },而不是匹配字母或数字),然后匹配一个空格,然后将任何一个或多个数字([^\W_]捕获到组2中。 (\d+)与所有不重叠的匹配,并且仅返回捕获的子字符串,这些子字符串被利用到动态生成的哈希中。

请注意,当您运行String#scan时,您不需要进行其他检查,因为b.to_i仅会匹配数字子串(输入中的长度为2)。

答案 1 :(得分:1)

我不认为使用正则表达式是创建哈希的最佳方法。相反,我建议使用方法String#splitHash::[]Hash#transform_valuesString#to_i。如果s是示例中给出的字符串,

Hash[*s.split].transform_values(&:to_i)
  #=> {"10c"=>10, "bj"=>18, "2s"=>15, "3s"=>3, "8d"=>8,
  #    "as" =>14, "kh"=>13, "8c"=> 8, "3c"=>3, "6d"=>6,
  #    "kc" =>13, "5d"=> 5, "ad"=>14} 

步骤如下。

a = s.split
  #=> ["10c", "10", "bj", ... , "14"] 
b = Hash[*a]
  #=> {"10c"=>"10", "bj"=>"18", "2s"=>"15", "3s"=>"3",
  #    "8d" => "8", "as"=>"14", "kh"=>"13", "8c"=>"8",
  #    "3c" => "3", "6d"=> "6", "kc"=>"13", "5d"=>"5",
  #    "ad" =>"14"} 
b.transform_values(&:to_i)
  #=> {"10c"=>10, "bj"=>18, "2s"=>15, "3s"=>3, "8d"=>8,
  #    "as" =>14, "kh"=>13, "8c"=> 8, "3c"=>3, "6d"=>6,
  #    "kc" =>13, "5d"=> 5, "ad"=>14} 

splat 运算符(*)将Hash[*a]评估为Hash["10c", "10", "bj", ... , "14"]

b.transform_values(&:to_i)在这里等效于b.transform_values { |v| v.to_i }