使用str
作为哈希中的键可以正常工作。
string = 'The dog and cat'
replace = {'dog' => 'woof', 'cat' => 'meow'}
replace.default = 'unknown'
string.gsub(/\w+/, replace)
# => "unknown woof unknown meow"
如何使用sym
作为哈希键获得相同的结果?
string = 'The dog and cat'
replace = {dog: 'woof', cat: 'meow'}
replace.default = 'unknown'
string.gsub(/\w+/, replace)
# => "unknown unknown unknown unknown" (actual result)
# => "unknown woof unknown meow" using symbols as hash keys? (desired result)
我做了一些尝试:
string.gsub(/(\w+)/, replace[:$1])
# => "unknown unknown unknown unknown"
string.split.map(&:to_sym).to_s.gsub(/\w+/, replace)
# => "[:unknown, :unknown, :unknown, :unknown]"
答案 0 :(得分:3)
在下面的代码中:
string = 'The dog and cat'
replace = {dog: 'woof', cat: 'meow'}
replace.default = 'unknown'
string.gsub(/\w+/, replace)
您创建了哈希replace
,默认值为'unknown'
。这意味着,当您从散列replace
中查找值时,如果该键不存在,则散列将返回unknown
作为值。当你以这种方式定义哈希时,它将以这种方式工作。
现在#gsub
方法,将所有单词匹配为'the'
,'dog'
等,但这些字符串都不是您的哈希replace
的关键,正如我所说如上所述,哈希replace
将每次unknown
返回默认值。
请记住 - 在哈希replace = {dog: 'woof', cat: 'meow'}
中,键是符号,例如:dog
,:cat
。但是#gsub
会将所有匹配作为字符串。
因此,要使其工作,您需要使用如下的块:
string = 'The dog and cat'
replace = {dog: 'woof', cat: 'meow'}
replace.default = 'unknown'
string.gsub(/\w+/) { |m| replace[m.to_sym] }
# => "unknown woof unknown meow"
答案 1 :(得分:1)
如果你想保留所有其他单词,但只是替换散列中的内容,你可以这样做:
replace = {'dog' => 'woof', 'cat' => 'meow'}
my_string = 'The dog and cat'
my_string.gsub(/\w+/) {|m| (replace.key? m) ? replace[m] : m}
将产生:
The woof and meow
或更紧凑(感谢@Arup提示):
my_string.gsub(/\w+/) {|m| replace.fetch(m, m)}
答案 2 :(得分:0)
目前尚不清楚为什么要用unknown
替换“未知”单词;这在普通的字符串处理或模板处理代码中并不是非常有用。结果,你似乎在问一个X-Y问题,想要知道当你应该做“X”时如何做“Y”。
以下是一些代码和可能有用的信息:
string = 'The dog and cat'
replacement_hash = {dog: 'woof', cat: 'meow'}
首先,要非常小心地使用与方法同名的变量。 Ruby可以弄明白你的意思,但是你的大脑总是无法建立连接。使用或维护代码的人的大脑可能效果不佳。因此,使用类似replace
的内容而不是名为replacement_hash
的哈希。
通常我们不想使用符号作为键来定义哈希,如果我们要对字符串进行搜索和替换操作。相反,我们想要实际的字符串值;这样更直接。也就是说,这将遍历带符号作为键的哈希,并使用等效字符串作为键生成新哈希:
replacement_hash2 = Hash[replacement_hash.keys.map(&:to_s).zip(replacement_hash.values)] # => {"dog"=>"woof", "cat"=>"meow"}
我们give gsub
a regular expression,它会遍历字符串,寻找与该模式匹配的内容。它的一个很酷的功能是我们可以给它一个哈希值,并且对于发现的每个匹配,它将查看相关的哈希并返回匹配键的值。
以下是如何轻松构建与哈希中的键匹配的模式。我使用的是不区分大小写的模式,但是YMMV:
key_regex = /\b(?:#{ Regexp.union(replacement_hash.keys.map(&:to_s)).source })\b/i # => /\b(?:dog|cat)\b/i
在最基本的形式中,这是一个gsub
,它使用模式在哈希值中查找值:
string.gsub(key_regex, replacement_hash2) # => "The woof and meow"
也可以使用模式搜索字符串,然后将“命中”传递给一个块,然后计算所需的替换:
string.gsub(key_regex) { |w| replacement_hash2[w] } # => "The woof and meow"
或:
string.gsub(key_regex) { |w| replacement_hash[w.to_sym] } # => "The woof and meow"
但是等等!还有更多!
如果您不想要手术方法,您还可以使用更通用的(“霰弹枪方法”)正则表达式模式,并在查看哈希值时处理命中和未命中:
string.gsub(/\S+/) { |w| replacement_hash[w.to_sym] || 'unknown' } # => "unknown woof unknown meow"
将原始代码转换为单个简单的代码行。根据需要更改正则表达式。
打坐这个是上面块的内容没有意义:
replacement_hash[:dog] # => "woof"
replacement_hash[:foo] # => nil
nil || 'unknown' # => "unknown"
请注意,使用replacement_hash
哈希将匹配的可疑/目标词转换为符号非常重要。这可能会变得棘手或复杂,因为某些字符串不会干净地转换为符号并导致双引号。您必须在哈希定义中考虑到这一点:
'foo'.to_sym # => :foo
'foo_bar'.to_sym # => :foo_bar
'foo-bar'.to_sym # => :"foo-bar"
'foo bar'.to_sym # => :"foo bar"