Ruby:为什么这个 WHEN 语句不适用于两个条件?
Ruby: why this WHEN-statement doesn't work with two conditions?
我的 Ruby 代码中有一个 case
基本上尝试以几种方式匹配字符串并相应地对其执行不同的操作,有点像这样:
case inst
when Rx_inst1
(some function)
when Rx_inst2
(some other function)
end
效果很好(我没有发布正则表达式,因为它非常非常长而且效果很好)。但是,当我尝试实施以下修改时,即使 RegEx 匹配字符串,如果它包含子字符串也不会执行条件:
case inst
when Rx_inst1
(some function)
when Rx_inst2 && !/dom\./
(some other function)
end
它 Rx_inst2
在等于 Nm. Friese = Fryzyjczyk, koń fryzyjski
或它之前匹配的任何其他类型的字符串时停止匹配 inst
。
我得到了与 && /dom\./
和 && inst.include?('dom.')
完全相同的结果,根据其他答案,这是正确的语法。我做错了什么?
很明显,Rx_inst2 && !/dom\./
returns(由于短路评估)第二个操作数的值,即!/dom\/
(前提是Rx_inst2
确实是Regexp
因此是真实的)。您可能需要在 Rx_inst2
中修改此正则表达式,没有简短的答案。
或者,您可以稍微更改所有这些 case
表达式,如下所示:
case
when inst =~ Rx_inst1
# (some function)
when inst =~ Rx_inst2 && !(inst =~ /dom\./)
# (some other function)
end
但在我看来,它并不是特别优雅的形式。
好的,原来是我让它这样工作的:
when (!inst.include?('dom.') and Rx_inst2)
我仍然不明白为什么我必须做以下所有这三件事:
- 更改操作顺序
- 将整个表达式用括号括起来
- 显式调用第一个,隐式调用第二个
case inst
when Rx_inst1
(some function)
when Rx_inst2 && !/dom\./
(some other function)
end
case 转换成一堆 if/elsif/else 语句与 .=== 运算符
所以你的代码等同于
if Rx_inst1 === inst
(some function)
elsif (Rx_inst2 && !/dom\./) === inst
(some other function)
end
和 (Rx_inst2 && !/dom\./) === inst
是这样工作的:
(Rx_inst2 && !/dom\./)
部分的计算结果为 !/dom\./
(Rx_inst2 是正则表达式,不是 nil 或 false)
!/dom\./ === inst
给你结果
所以
when Rx_inst2 && !/dom\./
匹配只要 !/dom\./ === inst
匹配
@Darigazz 很好地解释了 case
的工作原理以及您的代码为何有问题。您可以通过以下几种方式编写案例陈述。
#1
case inst
when Rx_inst1
m1
when Rx_inst2
m2 if inst.match? /dom\./
end
如果 m2 if inst.match? /dom\./
中有 inst.match? /dom\./ #=> false
,则返回 nil
。根据要求,if
可能会替换为 unless
。
#2
case inst
when Rx_inst1
m1
when /(?=.*dom\.)#{Rx_inst2}/
m2
end
其中 (?=.*dom\.)
是 正向预测 。例如,
Rx_inst2 = /Bubba|Trixie/
/(?=.*dom\.)#{Rx_inst2}/
#=> /(?=.*dom\.)(?-mix:Bubba|Trixie)/
根据要求,(?=.*dom\.)
可能会被 负前瞻 (?!.*dom\.)
.
取代
我的 Ruby 代码中有一个 case
基本上尝试以几种方式匹配字符串并相应地对其执行不同的操作,有点像这样:
case inst
when Rx_inst1
(some function)
when Rx_inst2
(some other function)
end
效果很好(我没有发布正则表达式,因为它非常非常长而且效果很好)。但是,当我尝试实施以下修改时,即使 RegEx 匹配字符串,如果它包含子字符串也不会执行条件:
case inst
when Rx_inst1
(some function)
when Rx_inst2 && !/dom\./
(some other function)
end
它 Rx_inst2
在等于 Nm. Friese = Fryzyjczyk, koń fryzyjski
或它之前匹配的任何其他类型的字符串时停止匹配 inst
。
我得到了与 && /dom\./
和 && inst.include?('dom.')
完全相同的结果,根据其他答案,这是正确的语法。我做错了什么?
很明显,Rx_inst2 && !/dom\./
returns(由于短路评估)第二个操作数的值,即!/dom\/
(前提是Rx_inst2
确实是Regexp
因此是真实的)。您可能需要在 Rx_inst2
中修改此正则表达式,没有简短的答案。
或者,您可以稍微更改所有这些 case
表达式,如下所示:
case
when inst =~ Rx_inst1
# (some function)
when inst =~ Rx_inst2 && !(inst =~ /dom\./)
# (some other function)
end
但在我看来,它并不是特别优雅的形式。
好的,原来是我让它这样工作的:
when (!inst.include?('dom.') and Rx_inst2)
我仍然不明白为什么我必须做以下所有这三件事:
- 更改操作顺序
- 将整个表达式用括号括起来
- 显式调用第一个,隐式调用第二个
case inst
when Rx_inst1
(some function)
when Rx_inst2 && !/dom\./
(some other function)
end
case 转换成一堆 if/elsif/else 语句与 .=== 运算符 所以你的代码等同于
if Rx_inst1 === inst
(some function)
elsif (Rx_inst2 && !/dom\./) === inst
(some other function)
end
和 (Rx_inst2 && !/dom\./) === inst
是这样工作的:
(Rx_inst2 && !/dom\./)
部分的计算结果为!/dom\./
(Rx_inst2 是正则表达式,不是 nil 或 false)!/dom\./ === inst
给你结果
所以
when Rx_inst2 && !/dom\./
匹配只要 !/dom\./ === inst
匹配
@Darigazz 很好地解释了 case
的工作原理以及您的代码为何有问题。您可以通过以下几种方式编写案例陈述。
#1
case inst
when Rx_inst1
m1
when Rx_inst2
m2 if inst.match? /dom\./
end
如果 m2 if inst.match? /dom\./
中有 inst.match? /dom\./ #=> false
,则返回 nil
。根据要求,if
可能会替换为 unless
。
#2
case inst
when Rx_inst1
m1
when /(?=.*dom\.)#{Rx_inst2}/
m2
end
其中 (?=.*dom\.)
是 正向预测 。例如,
Rx_inst2 = /Bubba|Trixie/
/(?=.*dom\.)#{Rx_inst2}/
#=> /(?=.*dom\.)(?-mix:Bubba|Trixie)/
根据要求,(?=.*dom\.)
可能会被 负前瞻 (?!.*dom\.)
.