【问题标题】:How to write replace function more elegant?如何写出更优雅的替换函数?
【发布时间】:2014-01-20 13:15:48
【问题描述】:

我写了一些函数来替换字符串中的一个值。 我需要一些时间才能根据各种文档弄清楚它,但我想问一些 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

【问题讨论】:

  • 作为一种风格,并且要编写惯用的 Ruby,不要在方法中使用带有 =begin/=end 的块 cmets,就好像 Ruby 是 Python 一样。相反,将其移到您的方法之前,并使用标准的# 注释标记。 RDoc 将能够自动找到该信息并将其合并到您的代码文档中。也使用两个空格来缩进,而不是四个。
  • 您应该展示一个预期输出的示例。 Rubular 提取物有助于查看您正在解析的内容,但它显示了您是如何做的,不一定是应该如何做,并且它无法向我们展示您的预期输出是。

标签: ruby regex optimization replace gsub


【解决方案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 用于,当块强烈需要显式声明的参数时,以及其他方式,例如在上面的代码中,它是不需要的,可以省略。同样对于上面的 ruby 等于 1.9 您可以使用命名组参数作为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

【讨论】:

  • 您能解释一下do | _ | 的用途吗?我的意思是,为什么是 | _ | 而不是对可读变量名的赋值?
  • @pduersteler _ 表示参数已通过,但未在函数或块中使用,请参见此处:github.com/bbatsov/ruby-style-guide#syntax
  • _ 这意味着未使用的变量。如果你不使用它,为什么你需要一个变量在块中?
  • @Monk_Code 有时需要,在上面的代码中不需要。我不打算省略它,以显示可用性,并增加代码的可读性
  • 如果不需要,可以不写。
【解决方案2】:

看起来您正在遵循一条非常迂回的路径来替换模式中的第 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 是一种从数组末尾索引并分配给该插槽的快速方法。那么代码只需要重新组装逗号分隔的字符串即可。

【讨论】:

  • 问题是这是文本文件的一部分,替换也可以是'='和','之间的字符串。但是感谢您也以其他方式呈现,我可能会在代码的其他部分使用它。 :)
猜你喜欢
  • 1970-01-01
  • 2011-12-16
  • 2010-09-29
  • 1970-01-01
  • 2012-08-26
  • 2017-07-31
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
相关资源
最近更新 更多