Ruby 在字符串中的任意位置匹配多个单词

Ruby 在字符串中的任意位置匹配多个单词,ruby,regex,Ruby,Regex,我想检查一个字符串selection中的所有单词是否存在于另一个字符串中。将有任意数量的单词。这不是一个OR。所有单词都必须出现在匹配器中。秩序并不重要。例如,当选择为“John Zeni”时,它必须匹配“John Paul Zeni”,因为“John”和“Zeni”都在匹配器中。如果选择只是“John”,那么它应该匹配,但是因为有多个单词,所以所有单词都必须匹配。需要正则表达式解决方案 这就是我所尝试的: selection = "John Zeni" pattern = selection.

我想检查一个字符串
selection
中的所有单词是否存在于另一个字符串中。将有任意数量的单词。这不是一个OR。所有单词都必须出现在匹配器中。秩序并不重要。例如,当
选择
“John Zeni”
时,它必须匹配
“John Paul Zeni”
,因为
“John”
“Zeni”
都在匹配器中。如果
选择
只是
“John”
,那么它应该匹配,但是因为有多个单词,所以所有单词都必须匹配。需要正则表达式解决方案

这就是我所尝试的:

selection = "John Zeni"
pattern = selection.split(" ").join("|")
# => "John|Zeni"
/#{Regexp.quote(pattern)}/
# => /John\|Zeni/ 
" John Paul Zeni".match(/#{Regexp.quote(pattern)}/)
# => nil 
为什么不匹配?问题在于
Regexp.quote
我认为。两个单词在匹配符中匹配是很重要的。这也不应匹配:

" John Paul Zeni" =~ /(John|Zach)/ 
# => 1

使用正面外观头部模拟

string = "Paul Zach"
re = '^(?=.*' + string.split(/\s+/).map{ |x| Regexp.quote(x) }.join(')(?=.*') + ')'
"John Paul Mak Zach Jack Zen" =~ /#{re}/
如果需要通过多行进行匹配,请启用
m
标志或使用
[\s\s]
而不是
。您可以使用单词周围的
\b
标记确保单词不在其他单词内


注意:顺序无关紧要。

使用正向lookaheads模拟

string = "Paul Zach"
re = '^(?=.*' + string.split(/\s+/).map{ |x| Regexp.quote(x) }.join(')(?=.*') + ')'
"John Paul Mak Zach Jack Zen" =~ /#{re}/
("John Zeni".split - "John Paul Zeni".split).empty?
  #=> true
如果需要通过多行进行匹配,请启用
m
标志或使用
[\s\s]
而不是
。您可以使用单词周围的
\b
标记确保单词不在其他单词内

注意:顺序不重要

("John Zeni".split - "John Paul Zeni".split).empty?
  #=> true
如果
str
可能包含标点符号,我们应该在拆分之前删除这些字符

("John Zeni Lola".split - "John Lola Paul, Zeni.".gsub(/[[:punct:]]/,'').split).empty?
  #=> true
如果
str
可能包含标点符号,我们应该在拆分之前删除这些字符

("John Zeni Lola".split - "John Lola Paul, Zeni.".gsub(/[[:punct:]]/,'').split).empty?
  #=> true


单独检查所有名称部分:
selection.split(“”)。all?{name | str.include?(name)}
@SergioTulentsev我需要一个正则表达式解决方案,因为最终我必须将其放入需要正则表达式的Mongoid查询中。使用lookaheads:
^(?=.*John)(?=.*Zeni)
为什么使用
Regexp.quote
?你有特殊的字符要解释吗?“需要正则表达式。”-不一定。即使在mongodb中,您也可以将invidual子句与
$结合起来,并单独检查所有名称部分:
selection.split(“”)。all?{name | str.include?(name)}
@SergioTulentsev我需要一个正则表达式解决方案,因为最终我必须将其放入需要正则表达式的Mongoid查询中。使用lookaheads:
^(?=.*John)(?=.*Zeni)
为什么要使用
Regexp.quote
?你有特殊的字符要解释吗?“需要正则表达式。”-不一定。即使在mongodb中,您也可以将invidual子句与
$和
组合在一起。您可能希望对其进行概括,以便它可以处理字符串中必须包含的任意数量的单词。谢谢。因为我不喜欢Ruby,所以我可能不去管代码部分。是的@CarySwoveland是对的。将有任意数量的单词。它不会总是两个。这就是我试图合并Regexp.quote的原因。@Donato如果您对单词不确定,我使用
map
为每个单词应用
Regexp.quote
。您需要分词,以便
字符串中的
“Paul”
“Paula”不匹配
在测试字符串中。您可能希望对其进行概括,以便它可以处理字符串中必须包含的任意数量的单词。谢谢。因为我不喜欢Ruby,所以我可能不去管代码部分。是的@CarySwoveland是对的。将有任意数量的单词。它不会总是两个。这就是我试图合并Regexp.quote的原因。@Donato如果您对单词不确定,我使用
map
为每个单词应用
Regexp.quote
。您需要分词,以便
字符串中的
“Paul”
“Paula”不匹配
在测试字符串中。您认为OP是否不想在
John Paul,Zeni
上找到匹配项?@revo,如果字符串可能包含标点符号,我建议作为预处理步骤删除这些字符(
str.gsub(/[:punct:]/,'')
)。你可能还想把每件事都降下来或升上去。如果你使用的是一个正则表达式,这可能不是必需的,但这样做会简化正则表达式。你可能希望对其进行推广,以便它能在任意分词器上工作。问题的最后一句(“需要正则表达式解决方案”)是在我发布答案后添加的。是的,但前两句话从未改变。你认为OP不想在
约翰·保罗,Zeni
上找到匹配项吗?@revo,如果字符串可能包含标点符号,我建议作为预处理步骤删除这些字符(
str.gsub(/[:punct:]/,'')
)。你可能还想把每件事都降下来或升上去。如果你使用的是一个正则表达式,这可能不是必需的,但这样做会简化正则表达式。你可能希望对其进行推广,以便它可以处理任意的分词符。问题的最后一句(“需要正则表达式解决方案”)是在我发布答案后添加的。是的,但前两句从未更改。