2011-07-07 60 views
3

這感覺像應該是一個非常簡單的事情與正則表達式,但我似乎無法弄清楚。正則表達式無序匹配

我想寫一個正則表達式,它檢查某個單詞列表是否以任何順序出現在文檔中,以及任何順序的任何其他單詞。

在布爾邏輯中,檢查將是: 如果allOfTheseWords在本文中並且atLeastOneOfTheseWords在本文中,則返回true。


我與(快樂或悲傷)搜索(約翰和巴巴拉)。 順序無關緊要。

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

我簡直無法弄清楚如何讓零件和零件在無序的情況下匹配,任何幫助將不勝感激!

+1

你確定你正在尋找一個正則表達式的解決方案嗎?如果你的應用程序假設要查詢很多時間,並且文本相對穩定,那麼你可能更喜歡信息檢索技術 – amit

+0

是的,它開始看起來像一個正則表達式不一定是我想要的。或者至少應該使用多個正則表達式,並且我需要以編程方式確保這些匹配。 – mrcleaver

回答

3

你真的不想使用正則表達式,除非文本非常小,這從你的描述我懷疑。

一個簡單的解決方案是將所有單詞轉儲到HashSet中,此時檢查單詞是否存在成爲一個非常快速和簡單的操作。

1

如果你確實需要一個單個正則表達式,那麼由於回溯,它會非常大且很慢。對於(約翰和芭芭拉)AND(高興或悲傷)您的特殊例子,它應該像這樣開頭:

\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

如果你想用正則表達式來做到這一點,我想嘗試positive lookahead

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

的表現應該是相當的allOfTheseWords做全文搜索每個單詞組分別。

+1

你可能想要避免在正則表達式和使用中貪婪。*?而是爲了獲得你聲稱的表現。 *在中間會在回溯之前結束。 –

0

它可能可以用正則表達式來完成,但它會非常複雜,所以最好使用一些不同的方法(例如使用HashSet,如其他答案中所述)。

正則表達式的一種方法是計算您正在查找的單詞的所有排列,然後編寫一個提到所有這些排列的正則表達式。用2個單詞將會有2個排列,如在(.*foo.*bar.*)|(.*bar.*foo.*)(加上單詞邊界)中,用3個單詞將會有6個排列,並且相當短的排列次數將比您的輸入文件更大。

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 

正如在其他反應mentionned,正則表達式可能不適合在這裏。

0

如果您的數據相對穩定,並且您正計劃搜索大量數據,則使用Apache Lucene將確保更好的性能。

使用信息檢索技術,你將首先索引你的所有文檔/句子,然後搜索你的單詞,在你的例子中你想搜索「+(+ john + barbara)+(悲傷的快樂)」[或者「(john and barbarar)AND(sad or happy)」]

這種方法在索引時會消耗一些時間,但是,搜索會比任何正則表達式/哈希集方法快得多(因爲您不需要迭代在所有文件...)