Ruby:在条件块中使用条件结果

Ruby:在条件块中使用条件结果,ruby,regex,Ruby,Regex,我有这样的密码 reg = /(.+)_path/ if reg.match('home_path') puts reg.match('home_path')[0] end 这将评估正则表达式两次:( 所以 但它会将变量结果存储在内存中,直到。 我有一个函数式编程的想法 /(.+)_path/.match('home_path').compact.each do |match| puts match[0] end 但似乎应该有更好的解决办法,不是吗?那么 if m=/rege

我有这样的密码

reg = /(.+)_path/
if reg.match('home_path')
    puts reg.match('home_path')[0]
end
这将评估正则表达式两次:( 所以

但它会将变量结果存储在内存中,直到。 我有一个函数式编程的想法

/(.+)_path/.match('home_path').compact.each do |match|
    puts match[0]
end
但似乎应该有更好的解决办法,不是吗?

那么

if m=/regex here/.match(string) then puts m[0] end
一个简洁的单线解决方案,我想:)

我个人最喜欢的(w/1.9+)是以下的一些变体:

if /(?<prefix>.+)_path/ =~ "home_path"
   puts prefix
end
if/(?。+)\u路径/=“主路径”
放置前缀
结束
如果你真的想要一行:
put/(?。+)\u path/=~'home\u path'?前缀:false


有关命名捕获的一些限制,请参见,并且有一些特殊的全局变量(它们的名称以
$
开头)包含上次regexp匹配的结果:

r = /(.+)_path/

# $1 - the n-th group of the last successful match (may be > 1)
puts $1 if r.match('home_path')
# => home 

# $& - the string matched by the last successful match
puts $& if r.match('home_path')
# => home_path
您可以找到预定义全局变量的完整列表

请注意,在上面的示例中,如果传递的字符串与regexp不匹配,则根本不会执行put

说到一般情况,你总是可以把任务本身考虑进去:

if m = /(.+)_path/.match('home_path')
  puts m[0]
end

尽管如此,许多人不喜欢这样做,因为这会降低代码的可读性,并给混淆
=
=

提供了一个很好的机会。实际上,这可以在没有任何条件的情况下完成。(如果不存在匹配项,则表达式的计算结果为“
。)

这个怎么样

puts $~ if /regex/.match("string")
$~
是一个特殊变量,用于存储最后一个regexp匹配项。更多信息:

来自:如果给定一个块,如果匹配成功,则使用MatchData调用该块

因此:


我仍然不能决定我是否喜欢那个功能。它悄悄地覆盖了对我来说相当危险的局部变量。说到一行程序解释器,它不允许你做
放m if/(?。+)/=~'qwe'
(如果
m
之前没有定义)这样会更好一些。它确实会发出警告,但我从不运行w/warnings。无论如何,谢谢你的展示,我不知道这个功能。@zeke警告是“命名捕获冲突一个局部变量-前缀”在匹配的行上。@Joshuache明白了。没有必要在条件之前设置
前缀=nil
。不匹配,表示前缀=nil。在Ruby方法更常见的上下文中(请参见:),局部变量问题被大大减少了。@zeke我在块之前定义
prefix=nil
的原因是模拟匹配器重写局部变量的情况。这就是导致调用警告的原因(与@KL-7抱怨“它悄悄地覆盖了局部变量”的反例)。除此之外,如果已经定义了var,单行版本
放置前缀if/(?)\u path/=~“home\u path”
将起作用,但会引发
名称错误
。但是
放置x if x
放置x.to\u s
x.nil?
将x.to_s
产生一个换行符,而
如果x
不产生换行符,则放置x。
puts /(.+)_path/.match('home_xath').to_a[0].to_s
puts $~ if /regex/.match("string")
/(.+)_path/.match('home_path') { |m| puts m[1] }  # => home

/(.+)_path/.match('homepath') { |m| puts m[1] }  # prints nothing