怎么写替换功能更优雅?

时间:2014-01-20 13:15:49

标签: ruby regex optimization replace gsub

我写了一些函数来替换字符串中的一个值。 我花了一些时间来根据varius文档找出它,但我想问一下RUBY中的一些冠军关于RIGHT WAY,如何编写代码?

def replace(newValue)
=begin
    [0]: A0000001561234 = 10,10,1,X,0,0,12345,12345
    1.  A0000001561234 =
    2.  10
    3.  10
    4.  1
    5.  X
    6.  0
    7.  0
    8.  12345
    9.  12345
    //source - http://rubular.com/
=end
    Dir.foreach('./') do |item|
        next if item == '.' or item == '..'
        if item =~ /(.*)online(.*)/
            IO.write(item, File.open(item) do |f| f.read.gsub(/^(A000[0-9]{10}.*)([0-9]{2})\,(.*)\,(.*)\,(.*)\,(.*)\,(.*)\,([1-5]*)\,([1-5]*)\n/x, "\\1\\2,\\3,\\4,\\5,\\6,\\7,#{newValue},\\9\n" ) end)
            puts "done"
        end
    end
end

2 个答案:

答案 0 :(得分:1)

可读的变体:

f.read.gsub( /^(A000[0-9]{10})\s*=\s*(.*)/ ) do | _ |
    values = $2.split( ',' )
    values[ 6 ] = new_value
    "A000#{$1} = #{values.join( ',' )}"
end

_表示参数已通过,但未在函数或块中使用,请参阅good code standart。当块强烈要求显式声明的参数时,使用_ shell,以及其他方式,例如,在上面的代码中,它不是必需的,可以省略。同样对于等于 1.9 ruby​​ ,您可以使用Regexp的命名组参数,因此可以按如下方式优化代码:

f.read.gsub( /^(?<key>A000[0-9]{10})\s*=\s*(?<valueset>.*)/ ) do
    values = valueset.split( ',' )
    values[ 6 ] = new_value
    "A000#{key} = #{values.join( ',' )}"
end

答案 1 :(得分:0)

看起来你正在遵循一条非常圆的路径来替换模式中的第8个捕获。相反,直接做,而不用过于复杂的正则表达式:

new_value = 'foobar'
str = 'A0000001561234 = 10,10,1,X,0,0,12345,12345'

values = str.split(',') # => ["A0000001561234 = 10", "10", "1", "X", "0", "0", "12345", "12345"]
values[-2] = new_value
values.join(',') # => "A0000001561234 = 10,10,1,X,0,0,foobar,12345"

values[-2] = new_value是从数组末尾索引并分配给该插槽的快速方法。然后代码只需要重新组合逗号分隔的字符串。