Ruby on rails 在ruby中作为方法条件传递字符串

Ruby on rails 在ruby中作为方法条件传递字符串,ruby-on-rails,ruby,conditional,whitelist,Ruby On Rails,Ruby,Conditional,Whitelist,是否有一种通过字符串操作创建条件的方法。下面是我试图将字符串作为条件传递给include?方法的代码 "hello eveyone in the house".include?(%w('hello' 'world' 'new\ york' 'place').join(" || ").to_s) include?的条件as参数是不可能的,因为include?只接受字符串参数 但你可以这样写: ['hello', 'world', 'new york', 'place'].any? { |w

是否有一种通过字符串操作创建条件的方法。下面是我试图将字符串作为条件传递给include?方法的代码

"hello eveyone in the house".include?(%w('hello' 'world' 'new\ york'    'place').join(" || ").to_s)

include?
的条件as参数是不可能的,因为
include?
只接受字符串参数

但你可以这样写:

['hello', 'world', 'new york', 'place'].any? { |word|
  "hello everyone in the house".include?(word)
}
或者可以从字符串生成regexp:

"hello eveyone in the house".match?(
  /#{['hello', 'world', 'new york', 'place'].join('|')}/
)

另一种可能性是使用以下词语:

警告:仅当白名单不包含任何包含多个单词的字符串时,此选项才有效。e、 g.
纽约
,原问题


有关更健壮的解决方案,请参见@spickermann的答案。

进行了一些基准测试,以测试速度,令我惊讶的是,spickerman的第一个解决方案是迄今为止在windows box上的MRI Ruby 2.3.0中速度最快的,其次是Crossion,而我自己的带有Regexp.union的解决方案最后一个:(


nince,但是您必须在Ruby<2.4中使用match,因为match?在以前的版本中不存在正确的
match?
最近在Ruby 2.4中引入。如果您使用的是较旧的版本,只需使用
match
即可。很好。如果您只需要一个布尔值作为答案,使用
any?
的优点还在于它可以阻止s一旦找到字符串。谢谢,我好像在尝试做一些你做不到的事情。试着在
a
的末尾加上“helllo”,看看这对结果有什么影响。事实上,@spickerman的方法在处理“hello”后退出,而其他的继续进行。编译
N
正则表达式,将
Regexp.union
移出循环,它可能是最快的。我对这个结果并不感到惊讶。构建Regexp并启动“Regexp引擎”与简单的字符串操作和字符串比较相比,它非常昂贵。它只适用于这样的简单用例,文本越长,条件越复杂,或者重复使用同一个regexp的频率越高,regexp的回报就越高。这不适用于由多个词组成的白名单术语(如本例中的
new york
)。因为在句子中
new york
将被拆分为
['new','york']
,而该数组与
[
new york
]
不相交。
sentence  = "hello everyone in the house"
whitelist = %w(hello world new-york place)

found_words = sentence.split & whitelist
p found_words        # => ["hello"]
p found_words.empty? # => false
require 'benchmark' 

s = "hello everyone in the house"
a = ['hello', 'world', 'new york', 'place']

N = 10_000

Benchmark.bmbm do |x| 
  x.report("Union         ") { N.times { s.match(Regexp.union(a)) }}
  x.report("Union and scan") { N.times { s.scan(Regexp.union(a)) }}
  x.report("Interpollation") { N.times { s.match(/#{a.join('|')}/)}}
  x.report("intersect     ") { N.times { s.split & a }}
  x.report("block         ") { N.times { a.any? { |word| s.include?(word)}}}
end 

Rehearsal --------------------------------------------------
Union            0.110000   0.000000   0.110000 (  0.116051)
Union and scan   0.124000   0.000000   0.124000 (  0.121038)
Interpollation   0.110000   0.000000   0.110000 (  0.105943)
intersect        0.015000   0.000000   0.015000 (  0.018456)
block            0.000000   0.000000   0.000000 (  0.001908)
----------------------------------------- total: 0.359000sec

                     user     system      total        real
Union            0.109000   0.000000   0.109000 (  0.111704)
Union and scan   0.125000   0.000000   0.125000 (  0.119122)
Interpollation   0.109000   0.000000   0.109000 (  0.105288)
intersect        0.016000   0.000000   0.016000 (  0.017283)
block            0.000000   0.000000   0.000000 (  0.001764)