正则表达式无序匹配

时间:2011-07-07 21:46:37

标签: java regex

这对于使用正则表达式来说应该是一件非常简单的事情,但我似乎无法弄明白。

我想写一个正则表达式,它检查某些单词的列表是否以任何顺序出现在文档中,以及任何顺序中的任何一组其他单词。

在布尔逻辑中,检查将是: 如果allOfTheseWords在此文本中且至少有一个或哪些词语在此文本中,则返回true。

示例
我正在寻找(约翰和芭芭拉)(快乐或悲伤)。 订单无关紧要。

"Happy birthday john from barbara" => VALID
"Happy birthday john"              => INVALID

我根本无法弄清楚如何以无顺序的方式获得和部分匹配,任何帮助都将不胜感激!

6 个答案:

答案 0 :(得分:4)

你真的不想使用正则表达式,除非文字非常小,从你的描述中我怀疑。

一个简单的解决方案是将所有单词转储到HashSet中,此时检查单词是否存在变得非常快速和简单。

答案 1 :(得分:3)

如果你想使用正则表达式,我会尝试 positive lookahead

// searching for (john and barbara) with (happy or sad)
"^(?=.*\bjohn\b)(?=.*\bbarbara\b).*\b(happy|sad)\b"

性能应与单独对 allOfTheseWords 组中的每个单词进行全文搜索相媲美。

答案 2 :(得分:1)

如果你真的需要一个单个正则表达式,那么由于回溯,它会非常大而且非常慢。对于你(约翰和芭芭拉)和(快乐或悲伤)的特定例子,它将从这样开始:

\bJohn\b.*?\bBarbara\n.*?\bHappy\b|\bJohn\b.*?\bBarbara\n.*?\bSad\b|......

你最终需要将所有组合放在正则表达式中。类似的东西:

JBH, JBS, JHB, JSB, HJB, SJB, BJH, BJS, BHJ, BSJ, HBJ, SBJ

再次回溯将是令人望而却步的,案件数量的爆炸也是如此。远离正则表达式。

答案 3 :(得分:1)

以您的示例为例,这是一个可以帮助您的正则表达式:

<强>正则表达式

(?:happy|sad).*?john.*?barbara|
(?:happy|sad).*?barbara.*?john|
barbara.*?john.*?(?:happy|sad)|
john.*?barbara.*?(?:happy|sad)|
barbara.*?(?:happy|sad).*?john|
john.*?(?:happy|sad).*?barbara

<强>输出

happy birthday john from barbara => Matched
Happy birthday john              => Not matched

正如其他回复中所提到的,正则表达式可能不适合这里。

答案 4 :(得分:0)

有可能使用regexp来实现它,但它会如此复杂以至于最好使用一些不同的方式(例如使用HashSet,如其他答案中所述)。

使用正则表达式执行此操作的一种方法是计算您要查找的单词的所有排列,然后编写正则表达式,其中提及所有这些排列。使用2个单词将有2个排列,如(.*foo.*bar.*)|(.*bar.*foo.*)(加上单词边界),3个单词将有6个排列,很快排列的数量将大于输入文件。

答案 5 :(得分:0)

如果您的数据相对稳定,并且您计划进行大量搜索,则使用Apache Lucene将确保更好的性能。

使用信息检索技术,您将首先索引所有文档/句子,然后搜索您的单词,在您的示例中,您希望搜索“+(+ john + barbara)+(悲伤快乐)”[或“(约翰和巴巴拉)和(悲伤或快乐)”]

这种方法在索引时会消耗一些时间,但是,搜索将比任何正则表达式/ hashset方法快得多(因为您不需要迭代所有文档......)