Ruby部分单词匹配

时间:2013-10-20 02:04:21

标签: ruby word expression match partial

我需要帮助找到部分单词匹配。它应该返回与目标三个连续字母匹配的单词。例如:

WORDS = ["born", "port" ,"cort", "mort"]
find_match("corn", WORDS)  =>  returns  ["born", "cort"]

应找到"corn"的部分匹配项。并且“b orn​​ ”和“ cor t”匹配。

正则表达式可能不是解决此类问题的最佳方法。如果您有其他想法,请随时分享。

2 个答案:

答案 0 :(得分:6)

您可以使用each_cons构建一个子字符串数组:

'corn'.chars.each_cons(3).map(&:join)
# ['cor', 'orn']

然后Regexp.union将数组转换为单个正则表达式:

re = Regexp.union('corn'.chars.each_cons(3).map(&:join))

然后,您可以将re与数组元素匹配:

WORDS.select { |w| w =~ re }

泛化:

def find_match(word, words)
    re = Regexp.union(word.chars.each_cons(3).map(&:join))
    words.select { |w| w =~ re }
end

我确信这个一般主题有很多变化。例如,您可以使用match_str形式的String#[]而不是正则表达式,我确信有很多不同的方法来提取长度为3的所有子字符串。

答案 1 :(得分:2)

非正则表达式解决方案:

WORDS = ["born", "port" ,"cort", "mort"]

def find_match(w)
  threes = (0..w.size-3).reduce([]) {|arr, i| arr << w[i,3]}
  WORDS.select {|w| threes.select {|s| w.include?(s)}.any?}
end

find_match("corn")   # => ["born", "cort"] 
find_match("cavort") # => ["port", "cort", "mort"]   
find_match("heart")  # => []
  • 首先计算threes,这是w所有子串的数组,长度为3。如果w = snort,则为['sno', 'nor', 'ort']w[0,3] = 'sno'w[1,3] = 'nor'w[2,3] = 'ort'
  • 接下来,选择WORDS中的字词,这些字词的子字符串至少与threes中的字符串匹配。

当然有很多变体,例如:

threes = []; (threes << w[0,3]; w.slice!(0)) while w.size > 2

对于上面的第二行,我最初尝试过

threes.reduce([]) {|arr1, s| arr1 += WORDS.select {|w| w.include?(s)}}

但这是有问题的,因为WORDS中的单词可能匹配w的多个3个字符的子字符串,在这种情况下,每个匹配都会包含arr1一次。