在Ruby中需要更好的正则表达式解决方案

时间:2015-09-23 08:22:29

标签: ruby regex

我有以下代码:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
name = "builder-#{date_time}"   # builder-20150923125450

if some_condition
  name.sub!("#{date_time}", "one-#{date_time}") # builder-one-20150923125450
end

以上代码工作正常。 但我认为这可能会更好,因为我觉得我在这里重复#{date_time}两次。

我听说过正则表达式capture and replace。我们可以在这里使用吗?如果是,怎么样?

3 个答案:

答案 0 :(得分:3)

要利用捕获机制,您需要使用圆括号围绕要在替换字符串中使用反向引用引用的子模式。

以下是一个例子:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
name = "builder-#{date_time}"
puts name.sub(/^([^-]*-)/, "\\1one-")

请参阅IDEONE demo

^([^-]*-)匹配并捕获字符串(-)开头的^以外的所有字符和连字符,然后我们使用{{1}来引用文本在替换字符串中。

有关详细信息,请参阅Use Parentheses for Grouping and Capturing at Regular-Expressions.info

更优化的方法是在初始化\\1变量时使用三元运算符:

name

IDEONE demo

答案 1 :(得分:1)

策略一 - 预先计算前缀:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
prefix    = some_condition ? 'builder-one-' : 'builder-'
name      = "#{prefix}#{date_time}"

字符串'builder-'在这里重复两次。显然,你可以干得更多,但它是一个矫枉过正的恕我直言。

<小时/> 策略二 - 使用前瞻:

date_time = Time.now.strftime('%Y%m%d%H%M%S')
name      = "builder-#{date_time}"

name.sub!(/(?=#{date_time})/, "one-") if some_condition

现在date_time只出现两次。我不会说这是一个很大的改进。我不会说开始时有很多问题。

答案 2 :(得分:0)

"builder-" + ("one-" if some_condition).to_s + date_time

date_time = "right now"

some_condition = true
"builder-" + ("one-" if some_condition).to_s + date_time
  #=> "builder-one-right now"

some_condition = false
"builder-" + ("one-" if some_condition).to_s + date_time
 #=> "builder-right now"   

请注意:

("one-" if false).to_s #=> nil.to_s => ""