2010-09-24 155 views
5

今天我被問到是否有一個庫需要一個字符串列表並計算出最有效的正則表達式來匹配那些字符串。我認爲這本身就是NP Complete problem,但我認爲我們可以稍微改進一下範圍。簡化正則表達式或模式

我將如何生成和簡化一個正則表達式來匹配我的網絡上一大組所有主機的主機子集? (知道我可能無法獲得最高效的正則表達式。)

第一步很簡單。從下面的列表中;

  • appserver1.domain.tld
  • appserver2.domain.tld
  • appserver3.domain.tld

我可以連接,並將它們逃進

appserver1\.domain\.tld|appserver2\.domain\.tld|appserver3\.domain\.tld 

我知道如何手動簡化正則表達式到

appserver[123]\.domain\.tld 

從那裏我可以測試該模式對主機的完整列表,並驗證它只匹配選定的3個主機。我不知道的是如何自動化簡化流程。是否有任何庫(Perl,Javascript或C#)或常見的做法?

感謝

更新我得到了一些真棒Perl模塊,但我會愛一個前端解決方案,以及。這意味着Javascript。我已經四處搜索,但沒有人將perl模塊移植到JS,並且我找不到搜索此類型庫的語言。

回答

7

Regex::PreSuf模塊旨在完成此操作。

引述梗概:

use Regex::PreSuf; 

my $re = presuf(qw(foobar fooxar foozap)); 

# $re should be now 'foo(?:zap|[bx]ar)' 
+0

好找!我想知道C#社區能夠想出什麼;) – 2010-09-24 15:35:51

+0

太棒了!我真的希望這也存在於JS中。 – reconbot 2010-09-24 15:45:59

3

Perl的正則表達式編譯器生成一個分支特里數據結構進行的與部分圖案共同跨越的替代品:

$ perl -Mre=debug -ce '"whatever" =~ /appserver1\.domain\.tld|appserver2\.domain\.tld|appserver3\.domain\.tld/' 
Compiling REx "appserver1\.domain\.tld|appserver2\.domain\.tld|appserver3\."... 
Final program: 
    1: EXACT <appserver> (5) 
    5: TRIEC-EXACT[123] (25) 
     <1.domain.tld> 
     <2.domain.tld> 
     <3.domain.tld> 
    25: END (0) 
anchored "appserver" at 0 (checking anchored) minlen 21 
-e syntax OK 
Freeing REx: "appserver1\.domain\.tld|appserver2\.domain\.tld|appserver3\."... 
+0

你能把編譯後的正則表達式當作字符串嗎? – reconbot 2010-10-12 16:16:17