Reputation: 9507
I want to check if all words in a string selection
are present in another string. There will be an arbitrary number of words. This is not an OR. All words MUST be present in the matcher. Order does not matter. For example, when selection
is "John Zeni"
, it must match " John Paul Zeni"
because both "John"
and "Zeni"
are in the matcher. If selection
was just "John"
, then it should match, but since there are multiple words, all words must match. Regex solution is required.
This is what I tried:
selection = "John Zeni"
pattern = selection.split(" ").join("|")
# => "John|Zeni"
/#{Regexp.quote(pattern)}/
# => /John\|Zeni/
" John Paul Zeni".match(/#{Regexp.quote(pattern)}/)
# => nil
Why doesn't it match? The problem is with Regexp.quote
I think. It is important that both words match in the matcher. This also should not match:
" John Paul Zeni" =~ /(John|Zach)/
# => 1
Upvotes: 0
Views: 515
Reputation: 110755
("John Zeni".split - "John Paul Zeni".split).empty?
#=> true
If str
may contain punctuation we should remove those characters before splitting.
("John Zeni Lola".split - "John Lola Paul, Zeni.".gsub(/[[:punct:]]/,'').split).empty?
#=> true
Upvotes: 4
Reputation: 48751
Use positive lookaheads to simulate AND
:
string = "Paul Zach"
re = '^(?=.*' + string.split(/\s+/).map{ |x| Regexp.quote(x) }.join(')(?=.*') + ')'
"John Paul Mak Zach Jack Zen" =~ /#{re}/
If matching through multiple lines is a need, enable m
flag or use [\s\S]
instead of .
. You can ensure that words are not within other words using \b
token around them.
Note: Order doesn't matter.
Upvotes: 1