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

eve*_*1nd 2 ruby regex

我有这样的代码

reg = /(.+)_path/
if reg.match('home_path')
    puts reg.match('home_path')[0]
end
Run Code Online (Sandbox Code Playgroud)

这将eval正则表达式两次:(所以...

reg = /(.+)_path/
result = reg.match('home_path')
if result
    puts result[0]
end
Run Code Online (Sandbox Code Playgroud)

但它会将变量结果存储在内存中直到.我有一个功能编程的想法

/(.+)_path/.match('home_path').compact.each do |match|
    puts match[0]
end
Run Code Online (Sandbox Code Playgroud)

但似乎应该有更好的解决方案,不是吗?

KL-*_*L-7 7

有一些特殊的全局变量(它们的名称以...开头$)包含最后一个正则表达式匹配的结果:

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
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到预定义全局变量的完整列表.

请注意,puts如果传递的字符串与正则表达式不匹配,则上述示例中根本不会执行.

谈到一般情况,你总是可以将赋值置于条件本身:

if m = /(.+)_path/.match('home_path')
  puts m[0]
end
Run Code Online (Sandbox Code Playgroud)

尽管如此,许多人并不喜欢这样,因为它使代码的可读性降低,并且提供了混淆=和混淆的好机会==.


Eze*_*lin 6

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

if /(?<prefix>.+)_path/ =~ "home_path"
   puts prefix
end
Run Code Online (Sandbox Code Playgroud)

如果你真的想要一个单行: puts /(?<prefix>.+)_path/ =~ 'home_path' ? prefix : false

有关命名捕获的一些限制, 请参阅Ruby Docs#=~.


Mar*_*oda 6

文档:如果给出了一个块,如果匹配成功,则使用MatchData调用该块.

所以:

/(.+)_path/.match('home_path') { |m| puts m[1] }  # => home

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