使用regex-Ruby将字符串替换为特定格式

使用regex-Ruby将字符串替换为特定格式,ruby,regex,hash,Ruby,Regex,Hash,下面是我的代码。 我有大约100个文本文件,我想以一种特定的格式替换大量字符串,其中包括一个与哈希映射中的键对应的值 如果您看一下下面的代码,就可以理解这个场景 require 'yaml' map = YAML.load(File.open("/Documents/final.yml")) Dir.glob('/Documents/**/*.txt') do |item| next if item == '.' or item == '..' contents = File.read

下面是我的代码。 我有大约100个文本文件,我想以一种特定的格式替换大量字符串,其中包括一个与哈希映射中的键对应的值

如果您看一下下面的代码,就可以理解这个场景

require 'yaml'

map = YAML.load(File.open("/Documents/final.yml"))

Dir.glob('/Documents/**/*.txt') do |item|
   next if item == '.' or item == '..'
contents = File.read(item)
newFile = File.open(item, "w")
contents  = contents.gsub(/My data\(@"([^"]+)",([^,]+),([^,]+),([^,]+)\)/) {'Your data(@'+ $1 +','+ $2 +',' + $3 + ',' + map[$1] + ',' + $4 + ')'}
newFile.write(contents)
end
出于某种原因,我得到如下错误[test2.rb是我的ruby脚本文件]

test2.rb:9:in `+': no implicit conversion of nil into String (TypeError)
from test2.rb:9:in `block (2 levels) in <main>'
from test2.rb:9:in `gsub'
from test2.rb:9:in `block in <main>'
from test2.rb:5:in `glob'
from test2.rb:5:in `<main>'
另外,如果我删除了其他字符串,并且只有map[$1],我仍然会得到预期的输出

contents  = contents.gsub(/My data\(@"([^"]+)",([^,]+),([^,]+),([^,]+)\)/) { map[$1] }
但两者结合起来是行不通的


任何帮助都将不胜感激

对于其中一个文件中的至少一个条目,
map[$1]
的值为
nil
。就其本身而言,它可以存储在一个数组中,并根据需要输出。使用
+
连接时,会导致您看到的错误

您可以使用
map[$1].to\s
强制转换为字符串。对于
nil
这将返回空字符串
”,这可能是您想要的


您还可以使用Ruby的内置字符串插值,它在内部执行相同的操作,并且与您的使用非常匹配。
.gsub
之后的块可以是
{“您的数据(@{$1}、{$2}、{$3}、{map[$1]}、{$4})
对于至少一个文件中的一个条目,
map[$1]
的值为
nil。就其本身而言,它可以存储在一个数组中,并根据需要输出。使用
+
连接时,会导致您看到的错误

您可以使用
map[$1].to\s
强制转换为字符串。对于
nil
这将返回空字符串
”,这可能是您想要的


您还可以使用Ruby的内置字符串插值,它在内部执行相同的操作,并且与您的使用非常匹配。
.gsub
之后的块可以是
{“您的数据(@{$1}、{$2}、{$3}、{map[$1]}、{$4})
对于至少一个文件中的一个条目,
map[$1]
的值为
nil。就其本身而言,它可以存储在一个数组中,并根据需要输出。使用
+
连接时,会导致您看到的错误

您可以使用
map[$1].to\s
强制转换为字符串。对于
nil
这将返回空字符串
”,这可能是您想要的


您还可以使用Ruby的内置字符串插值,它在内部执行相同的操作,并且与您的使用非常匹配。
.gsub
之后的块可以是
{“您的数据(@{$1}、{$2}、{$3}、{map[$1]}、{$4})
对于至少一个文件中的一个条目,
map[$1]
的值为
nil。就其本身而言,它可以存储在一个数组中,并根据需要输出。使用
+
连接时,会导致您看到的错误

您可以使用
map[$1].to\s
强制转换为字符串。对于
nil
这将返回空字符串
”,这可能是您想要的


您还可以使用Ruby的内置字符串插值,它在内部执行相同的操作,并且与您的使用非常匹配。
.gsub
之后的块可以是
{“您的数据(@{$1}、{$2}、{$3}、{$map[$1]}、{$4})
要扩展@Neiller的答案,这将是一个可能的干净解决方案:

contents.gsub(/My data\(@"([^"]+)",([^,]+),([^,]+),([^,]+)\)/) do
  values = [$1, $2, $3, map[$1], $4].join(',')
  "Your data(@#{values})"
end
在这种情况下,
join
将对数组内容隐式调用
。但是,这意味着如果在
映射中找不到值,您将得到一个空值,例如

你的数据(@123,a,b,c)

如果要忽略此项,请在加入阵列之前调用阵列上的
compact
,最终得到

你的数据(@123,a,b,c)


要扩展@NeilSlater的答案,这将是一个可能的干净解决方案:

contents.gsub(/My data\(@"([^"]+)",([^,]+),([^,]+),([^,]+)\)/) do
  values = [$1, $2, $3, map[$1], $4].join(',')
  "Your data(@#{values})"
end
在这种情况下,
join
将对数组内容隐式调用
。但是,这意味着如果在
映射中找不到值,您将得到一个空值,例如

你的数据(@123,a,b,c)

如果要忽略此项,请在加入阵列之前调用阵列上的
compact
,最终得到

你的数据(@123,a,b,c)


要扩展@NeilSlater的答案,这将是一个可能的干净解决方案:

contents.gsub(/My data\(@"([^"]+)",([^,]+),([^,]+),([^,]+)\)/) do
  values = [$1, $2, $3, map[$1], $4].join(',')
  "Your data(@#{values})"
end
在这种情况下,
join
将对数组内容隐式调用
。但是,这意味着如果在
映射中找不到值,您将得到一个空值,例如

你的数据(@123,a,b,c)

如果要忽略此项,请在加入阵列之前调用阵列上的
compact
,最终得到

你的数据(@123,a,b,c)


要扩展@NeilSlater的答案,这将是一个可能的干净解决方案:

contents.gsub(/My data\(@"([^"]+)",([^,]+),([^,]+),([^,]+)\)/) do
  values = [$1, $2, $3, map[$1], $4].join(',')
  "Your data(@#{values})"
end
在这种情况下,
join
将对数组内容隐式调用
。但是,这意味着如果在
映射中找不到值,您将得到一个空值,例如

你的数据(@123,a,b,c)

如果要忽略此项,请在加入阵列之前调用阵列上的
compact
,最终得到

你的数据(@123,a,b,c)


或者更好的方法是,将字符串插值与
“..{map[$1]}…”
一起使用,它将隐式调用
。或者更好的方法是,将字符串插值与
“..{map[$1]}…”
一起使用,它将
隐式调用到
。或者更好的方法是,将字符串插值与
“..{map[$1]}”一起使用
将隐式调用
。或者更好地,使用字符串插值和
“…{map[$1]}…”
将隐式调用