如果它们(正则表达式)匹配Ruby中第二个数组中的字符串,我如何有效地拒绝数组中的字符串?

时间:2009-12-06 19:06:13

标签: ruby arrays

我有两个字符串数组,例如句子和单词。如果在一个句子中找到任何单词,例如sentence =~ /#{word}/我想拒绝句子数组中的句子。这很容易用双循环,但我想知道是否有更有效的方法来做这个,可能是逻辑运算符?

4 个答案:

答案 0 :(得分:1)

Array subtraction是你的朋友:

words.each do |word|
  sentences -= sentences.grep(/#{word}/)
end

它仍然是相同的基本时间复杂度(可能整体效率较低),但你可以绕过写出双循环。

请注意,使用此解决方案,单词不必匹配句子中整个空格分隔的单词。因此,单词cat会删除句子:String concatenation is gross

答案 1 :(得分:1)

将字符串连接到Regexp是一个非常糟糕的主意,因为回溯会使事情变得非常糟糕,因为你很快就会对正则表达式的大小产生限制。 (虽然如果wordarray很小,它可能在实践中运作良好)

考虑使用DictionaryMatcher Ruby Quiz解决方案之一。

然后你可以按如下方式操作:

dm=DictionaryMatcher.new
wordarray.each{|w| dm << w}
sentencearray.reject{|s| s =~ dm}

答案 2 :(得分:0)

您可以将所有单词合并为一个正则表达式,单词由“|”分隔字符。

sentence =~ /word1|word2|..../

您可以使用array.join(“|”)将单词数组转换为合适的正则表达式。

如果单词可能包含正则表达式元字符,则将每个单词括在非捕获括号中。

sentence =~ /(?:word1)|(?:word2)|..../

使用单个正则表达式应该比循环单词数组更有效,因为正则表达式将被编译成单个状态表。

答案 3 :(得分:0)

words = [...]
sentences = [....]

result = sentences.select{|sentence| !words.any?{|word| sentence =~ /#{word}/}}