检测数组中的单词是否与给定字符串+正则表达式匹配的算法?红宝石

时间:2013-12-24 19:48:54

标签: ruby regex arrays

我正在尝试构建一个简单的算法来检测数组中的单词是否与给定字符串(在本例中为g)唯一匹配 - 例如,只有1个字符的外观,以及无限量元音的出现 - aeiouy。

g = "bs"


arr = ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss']

for y in arr
  return y if y.include? { |z| /[aeiouy]/ =~ z } and y.include? { |z|/[ #{g} ]/ =~ z }

end

预期产出:

base
bees
# all others either have more than 1 b or s, or contain other consonants.

出现此错误:

include?': wrong number of arguments (0 for 1) (ArgumentError)

我认为使用.find或.any会有更好的方法吗?也许?

4 个答案:

答案 0 :(得分:2)

使用Array#grep方法(core lib)和String#countcodelib

我们只查找包含字符(b和s)的单词。

g = ["b", "s"]    
arr = ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss']

arr.grep(/[aeiouy]/).select { |w| g.all? { |s| w.count(s) == 1  } }

答案 1 :(得分:1)

如果要考虑字符的顺序:

g = "bs"
arr = ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss']
arr.select{|w| w.tr("aeiouy", "") == g}

如果不考虑字符的顺序:

g = "bs"
g = g.each_char.sort
arr = ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss']
arr.select{|w| w.tr("aeiouy", "").each_char.sort == g}

答案 2 :(得分:0)

这就是你想要的:

2.0.0p247 :122 > ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss'].select do |x|  
  x.match /^(?>b)[^bs]*(?>s)[^bs]*\b/
end
=> ["base", "bees"]

修改

匹配无限量的元音aeiouy

['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss'].select do |x|
  x.match /^(?>b)[aeiouy]*(?>s)[aeiouy]*\b/
end
=> ["base", "bees"]

答案 3 :(得分:0)

根据问题中的样本,我假设有两种情况:

  1. g = "bs"上的辅音顺序应在目标中保持相同。
  2. 辅音的顺序无关紧要。所以它g = "bs"也会匹配字符串“sb”,“sabe”,“sob”,“boose”等。
  3. 案例1:

    您可以先从arr数组中的目标字词中删除所有元音。然后将其与g中的模式匹配,并仅选择匹配的单词。

    g = "bs"
    arr = ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss']
    arr.map{ |x| [x, x.gsub(/[aeiou]/,'')] }.select{ |x| x[1] == g }.map{|x| x[0]}
    # ["base", "bees"]
    

    对于case2,只需在匹配前对源字符串字符和目标字符串字符进行排序:

    g = "bs"
    arr = ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss']
    v1 = arr.map{ |x| [x, x.gsub(/[aeiou]/,'')] }.select{ |x| x[1] == g }.map{|x| x[0]}
    p v1 
    # ["base", "bees"]
    
    arr = ['base', 'vase', 'race', 'bees', 'bass', 'sabb', 'babss', "sb", "sabe", "sob", "boose"]
    v2 = arr.map{ |x| [x, x.gsub(/[aeiou]/,'')] }.select{ |x| x[1].split("").sort == g.split("").sort }.map{|x| x[0]}
    p v2
    # ["base", "bees", "sb", "sabe", "sob", "boose"]
    

    根据arr中的数据量,您可以保留预处理的中间值,以获得更快的结果。