Ruby 在这种情况下,正则表达式比数组比较快吗?

Ruby 在这种情况下,正则表达式比数组比较快吗?,ruby,regex,arrays,performance,parsing,Ruby,Regex,Arrays,Performance,Parsing,假设我有一个传入字符串,我想扫描它,看看它是否包含我选择的“坏”字:) 将字符串拆分为一个数组,并将坏字保留在一个数组中,然后遍历每个坏字和每个传入字,查看是否有匹配项,是否更快,类似于: badwords.each do |badword| incoming.each do |word| trigger = true if badword == word end end 或者这样做更快: incoming.each do |word| trigger = true if badwo

假设我有一个传入字符串,我想扫描它,看看它是否包含我选择的“坏”字:)

将字符串拆分为一个数组,并将坏字保留在一个数组中,然后遍历每个坏字和每个传入字,查看是否有匹配项,是否更快,类似于:

badwords.each do |badword|
 incoming.each do |word|
  trigger = true if badword == word
 end
end
或者这样做更快:

incoming.each do |word|
 trigger = true if badwords.include? word
end
或者让字符串保持原样并使用类似以下内容的正则表达式运行.match()会更快:

/\bbadword1\b|\bbadword2\b|\bbadword3\b/

或者性能差异几乎可以忽略不计?有一段时间我一直在想这个问题。

一旦它被编译,Regex是现实生活中最快的(即非常长的传入字符串,许多类似的坏单词,等等),因为它可以在
传入的
上运行,并将处理“坏单词”的重叠部分非常好。

当正则表达式找到匹配项时,它不会停止循环,这给了它一个优势。尝试:

incoming.find{|word| badwords.include? word}
我的钱仍在正则表达式上,但应简化为:

/\b(badword1|badword2|badword3)\b/
或者让它成为一场公平的战斗:

/\a(badword1|badword2|badword3)\z/

答案可能取决于要检查的坏单词的数量:如果只有一个坏单词,可能不会有很大的区别,如果有50个坏单词,那么检查数组可能会变慢。另一方面,对于几十个或几十万个单词,regexp可能也不会太快


如果你需要处理大量的坏词,你可能会考虑分解成单个单词,然后使用Bloom Filter来测试这个词是否可能是坏的。

< P>这不完全回答你的问题,但是这肯定会帮助解决它。 举几个例子,看看你的目标是什么,并把它们放在基准点上

您可以找到如何在ruby中进行基准测试

只需将varoius表单放在报告块之间,获得基准,然后自己决定什么最适合自己

为了获得更好的解决方案,请使用真实数据进行测试


基准测试总是优于讨论:)

如果要扫描字符串中出现的单词,请使用查找它们

用于构建在黑名单中查找字符串的模式。您需要使用
\b
包装结果,以强制匹配单词边界,并使用不区分大小写的搜索

要让您了解
Regexp.union
如何提供帮助,请执行以下操作:

words = %w[foo bar]

Regexp.union(words)
=> /foo|bar/

'Daniel Foo killed him a bar'.scan(/\b#{Regexp.union(words)}\b/i)
=> ["foo", "bar"]
如果需要更多控制,还可以使用
Regexp.new
/…/
构建模式:

Regexp.new('\b(?:' + words.join('|') + ')\b', Regexp::IGNORECASE)
=> /\b(?:foo|bar)\b/i

/\b(?:#{words.join('|')})\b/i
=> /\b(?:foo|bar)\b/i

'Daniel Foo killed him a bar'.scan(/\b(?:#{words.join('|')})\b/i)
=> ["Foo", "bar"]
作为一个建议,黑名单上的单词很容易被用户欺骗,并且经常给出错误的结果,因为许多“冒犯性”单词只是在特定上下文中具有冒犯性。用户可以故意拼错它们或使用“l33t”语音,并且有几乎取之不尽的替代拼写,这将使您不断更新您的列表。对某些人来说,愚弄一个系统是一种享受


有一次,我被赋予了一个类似的任务,并写了一个翻译来为“冒犯性”单词提供替代拼写。我从从互联网上收集的单词和术语列表开始,并开始运行代码。在向数据库中添加了数百万个备选方案之后,我拔掉了插头,向管理层表明这是一件愚蠢的差事,因为愚弄它是微不足道的

停止疑惑,开始测量。通过使用非捕获组,您可以获得另一个轻微的性能提升。太棒了。你能告诉我为什么。在ruby docs数组#find中,find没有列为方法吗?是的,它是数组包含的可枚举模块的一部分。好提示。在我的例子中,我并没有过滤掉这些单词,只是简单地扫描看看是否有——在这种情况下,如果查询包含顽皮的单词,我需要提供不同的结果。