2010-09-24 102 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