好的,抓住你的帽子:
HASH_LIST = {
"ruby" => "fun to learn",
"the rails" => "It is a framework"
}
test_string = "I am learning the ruby by myself and also the rails."
keys_regex = /\b (?:#{Regexp.union(HASH_LIST.keys).source}) \b/x # => /\b (?:ruby|the\ rails) \b/x
test_string.gsub(keys_regex, HASH_LIST) # => "I am learning the fun to learn by myself and also It is a framework."
Ruby 有一些很棒的技巧,其中之一就是我们如何在gsub 处抛出一个正则表达式和一个哈希,它会搜索正则表达式的每个匹配项,查找匹配的“命中” " 作为哈希中的键,并将值替换回字符串:
gsub(pattern, hash) → new_str
...如果第二个参数是一个Hash,匹配的文本是它的key之一,对应的值就是替换字符串......
Regexp.union(HASH_LIST.keys) # => /ruby|the\ rails/
Regexp.union(HASH_LIST.keys).source # => "ruby|the\\ rails"
请注意,第一个返回一个正则表达式,第二个返回一个字符串。当我们将它们嵌入到另一个正则表达式中时,这一点很重要:
/#{Regexp.union(HASH_LIST.keys)}/ # => /(?-mix:ruby|the\ rails)/
/#{Regexp.union(HASH_LIST.keys).source}/ # => /ruby|the\ rails/
由于?-mix: 标志,第一个可以悄悄地破坏您认为的简单搜索,这最终会在模式中嵌入不同的标志。
Regexp documentation 很好地涵盖了这一切。
此功能是在 Ruby 中制作超高速模板例程的核心。