ruby - 如何在 Ruby 中使用散列键进行这些字符串替换?

标签 ruby

我有一堆 JSON 文件,用 Python 和 Ruby 处理,看起来像这样:

{
    "KEY1": "foo",
    "KEY2": "bar",

    "URL": "https://{KEY2}.com/{KEY1}",
    "IMPORTANT_THING": "repos/{KEY1}",
    "NOTE": "This thing is {KEY1}{KEY2}ed",
    "PYTHON_ONLY_THING": "{}/test/{}.py"
}

请注意,键的显示顺序不一致,我不想更改 JSON。

这是我的测试代码,显示了我到目前为止所做的尝试:

my_config = {"KEY1"=>"foo",
             "KEY2"=>"bar",
             "URL"=>"https://{KEY2}.com/{KEY1}",
             "IMPORTANT_THING"=>"repos/{KEY1}",
             "NOTE"=>"This thing is {KEY1}{KEY2}ed",
             "PYTHON_ONLY_THING"=>"{}/test/{}.py"}

my_config.each_key do |key|
    # Braindead, hard-coded solution that works:
    # my_config[key].gsub!("{KEY1}", my_config["KEY1"])
    # my_config[key].gsub!("{KEY2}", my_config["KEY2"])

    # More flexible (if it would work):
    # my_config[key].gsub!(/{.*}/, my_config['\0'.slice(1,-2)])
    my_config[key].gsub!(/{.*}/) {|s| my_config[s.slice(1,-2)]}
end

puts my_config

我现在正在使用 braindead 解决方案,它会产生预期的输出:

{"KEY1"=>"foo", "KEY2"=>"bar", "URL"=>"https://bar.com/foo", "IMPORTANT_THING"=>"repos/foo", "NOTE"=>"This thing is foobared", "PYTHON_ONLY_THING"=>"{}/test/{}.py"}

但我想让它更加灵活和可维护。第一个“更好”的解决方案显然会引发错误,因为 slice 对 '\0' 本身而不是匹配项进行操作,而且我不确定它是否会匹配多次。当前未注释的解决方案不起作用,因为第二部分似乎一次对一个字母进行操作,而不是像我预期的那样对每个匹配项进行操作,因此它只是删除了花括号中的内容。更糟糕的是,它会删除 PYTHON_ONLY_THING 中外括号之间的所有内容,这并不好。

我认为我需要同时更改正则表达式和 Ruby 代码才能正常工作,但我不确定到哪里寻求更多帮助。或者 gsub 可能不是这项工作的正确工具。有什么想法吗?

我在 Linux x86_64 上使用 Ruby 2.3.7。

最佳答案

使用String#gsub带有用于替换的初始哈希:

my_config.map do |k, v|
  [
    k,
    v.gsub(/(?<={)[^}]+(?=})/, my_config).gsub(/{(?!})|(?<!{)}/, '')
  ]
end.to_h
#⇒ {"KEY1"=>"foo",
#   "KEY2"=>"bar",
#   "URL"=>"https://bar.com/foo",
#   "IMPORTANT_THING"=>"repos/foo",
#   "NOTE"=>"This thing is foobared",
#   "PYTHON_ONLY_THING"=>"{}/test/{}.py"}

从 Ruby 2.4(或使用 Rails)开始,使用 Hash#transform_values 可能会更简单。

如果您不喜欢第二个 gsubbing,请提前转换哈希:

my_substs = my_config.map { |k, v| ["{#{k}}", v] }.to_h
my_config.map do |k, v|
  [k, v.gsub(/{[^}]+}/, my_substs)]
end.to_h

关于ruby - 如何在 Ruby 中使用散列键进行这些字符串替换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50841540/

相关文章:

ruby-on-rails - 如何获取调用别名方法的名称?

ruby - 无法安装pushmeup插件

ruby-on-rails - 有时会出现 ActiveRecord::AssociationTypeMismatch 错误

ruby - 如何运行 Ruby Gem?

ruby - 是否可以在 Ruby 中创建(或模拟)关键字?

html - 从 ruby​​onrails 中的字符串中提取 header 标签

ruby - RedCloth 破坏了我的 Rails 3 博客

ruby - 关于迭代数组以在哈希中生成频率的问题

ruby - 获取 libxml2.2.dylib "file is not of required architecture"错误

mysql - 添加refinerycms gem后迁移数据库的问题