Regular expression: if three letters are included
I've got a number of word:
hello, poison, world, search, echo ...
And I've got some letters e, h, o
Now I need to find all words that includes this letters. Like search, echo
for e, h, o
I can search this way:
words = %w[hello poison world search echo]
matched = words.select do |w|
%w[e,h,o].all?{ |l| w =~ /#{l}/ }
end
The problem is that if letters are o, o, o
, or l, b, l
this search will return true for words like open
or boil
, but 开发者_运维百科I need to search words that includes three of o
or two of l
and one b
upd:
leters = "abc"
words.select{ |w| w.count(letters) >= 3 }
upd 2
Bad solution, example:
"lllllll".count("lua") #=> 5
Are you sure you want a regexp? Strings support counting values in them, you could use that feature. Something like this:
words = ["pool", "tool", "troll", "lot"]
letters = "olo"
#find how many of each letter we need
counts = {}
letters.each { |v| counts[v] = letters.count(v) }
#See if a given work matches all the counts
# accumulated above
res = words.select do |w|
counts.keys.inject(true) do |match, letter|
match && (w.count(letter) == counts[letter])
end
end
It's probably best not to use regular expressions for this, but it can be done:
All three letters different:
/^(?=.*a)(?=.*b).*c/
Two the same and one different:
/^(?=.*a.*a).*b/
All three the same:
/^.*a.*a.*a/
Consider modifying the word (so that it becomes smaller with each check).
words = %w(fooo for find o ooo)
matched = words.select do |orig|
# note: str.gsub! returns nil if nothing was replaced
w = orig.clone
%w(o o o).all?{ |l| w.gsub!(/^(.*)(#{l})(.*)$/, '\1\3') }
end
Looks crazy, but it works:
leters = "abc"
words.select{ |w| w.count(letters) >= 3 }
But it isn't work with cyrillic letters :(
精彩评论