我有一个简单的Ruby脚本,可以从文件中读取数据,这是一个数据样本;
"SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020"
"T001 T665 CAR99A B0932 S222 LA44 V1009 V0029"
我试图根据每个单词的第一个字母找到匹配和替换整个单词的方法。例如。 ' Sxxxxxx'应该替换为“SWT'”,“Vxxxx”等字样。替换为' VAL'
我希望输出为
"SWR CAR BOT BOT BOT VAL VAL"
"TNK TNK CAR BOT SWT LTC VAL VAL"
示例代码;
File.open('test.txt').each do |line|
output = line.gsub!('V', 'VAL')
puts output
到目前为止我是否已经尝试过(显然无法正常工作,因为它将VAL的任何实例替换为VAL)
这是为了自动化生成机器可读配置文件的过程。
答案 0 :(得分:3)
使用正则表达式:
File.open('test.txt').each do |line|
output = line.gsub!(/\bV[^\s]*/, 'VAL')
puts output
end
编辑:
对于多次替换,我建议使用哈希而不是case-when
之类的内容,并构建如下所示的regexp:
replacements = { 'V' => 'VAL', 'S' => 'SWT' }
str = "SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020"
str.gsub(/\b(V|S)[^\s]*/) {|s| replacements[$1] }
#=> "SWT CAR03 B0932 B23(B) B32(A) VAL VAL"
答案 1 :(得分:0)
因为听起来你想要每行映射几个值,我不确定你是否想要使用gsub。这是一个使用map的示例。您可以在语句中添加任意数量的案例。
test.txt的内容
SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020
T001 T665 CAR99A B0932 S222 LA44 V1009 V0029
解析器
results = File.open('test.txt').each.map do |line|
mapped_line = line.split.map do |w|
case w
when /^S/
"SWT"
when /^V/
"VAL"
else
w
end
end
mapped_line.join " "
end
puts results
答案 2 :(得分:0)
SUBS = { "S"=>"SWT", "C"=>"CAR", "B"=>"BOT", "V"=>"VAL", "T"=>"TNK", "L"=>"LTC" }
def sub(str)
str.gsub(/[A-Z0-9\(\)]+/i) { |word| SUBS[word[0]] }
end
sub "SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020"
#=> "SWT CAR BOT BOT BOT BOT VAL VAL"
sub "T001 T665 CAR99A B0932 S222 LA44 V1009 V0029"
#=> "TNK TNK CAR BOT SWT LTC VAL VAL"
返回一个新字符串,保持原始字符串不变。如果您希望更改现有字符串,请使用gsub!
而不是gsub
。
这种方法的一个变体是使用默认块创建一个空哈希,然后将该哈希用作gsub
的第二个参数:
SUBS = Hash.new do |h,k|
case k[0]
when "S" then "SWT"
when "C" then "CAR"
when "B" then "BOT"
when "V" then "VAL"
when "T" then "TNK"
when "L" then "LTC"
end
端
def sub(str)
str.gsub(/[A-Z0-9\(\)]+/i, SUBS)
end
sub "SW02 CAR03 B0932 B23(B) B32(A) V1000 V0020"
#=> "SWT CAR BOT BOT BOT BOT VAL VAL"
sub "T001 T665 CAR99A B0932 S222 LA44 V1009 V0029"
#=> "TNK TNK CAR BOT SWT LTC VAL VAL"
请参阅文档String#gsub。