正则表达式:分隔扩展名

时间:2014-11-02 07:52:23

标签: php regex string file-extension

我试图制定最短的正则表达式,以检查参数标记(在字符串中)是否包含某个文件扩展名。

我要检查的扩展程序是:

asp,aspx,cfm,cgi,fcgi,dll,htm,html,shtm,shtml,jhtml,phtml,xhtm,rbml,jsp,php,phps,php4

目前,我有以下表达方式:

aspx?|cfm|f?cgi|dll|s?html?|jhtml|phtml|xhtm|rbml|jsp|phps?|php4

我确定这样做的方法较短,但我不是RegEx瘾君子,所以我不是最好的。

2 个答案:

答案 0 :(得分:3)

你可以结合其中一些:

aspx?|cfm|f?cgi|dll|s?html?|[jp]html|xhtm|rbml|jsp|php[s4]?

然而,在我看来,你原来的正则表达式很好。更短不一定更好。单独列出所有案例可以更清楚地了解您正在做什么。合并大量案例使其难以理解。

答案 1 :(得分:1)

要构建以替换开头的高效模式,您只需要考虑每个替代项的第一个字符。原因是一旦第一个字符匹配,您就不需要测试另一个替代字符。在这里,如果我计算列表中每个第一个字符的出现次数,我会得到:

p:4
a,c,h,j,s:2
d,f,r,x:1

因此,模式将如下所示:

(?:p...|a...|c...|h...|j...|s...|d...|f...|r...|x...)

现在,我只需要填写交替的每个成员:

(?:ph(?:p[4s]?|tml)|aspx?|c(?:fm|gi)|html?|j(?:html|sp)|shtml?|dll|fcgi|rbml|xhtm)

但是交替特别是在模式开始时有成本,因为必须针对字符串中的每个字符测试交替的每个成员,包括不是交替中的第一个字符之一的字符。为避免此问题,您可以使用第一个字符识别技术来减少对相关字符的测试。

(?=[acdfhjprsx])(?:ph(?:p[4s]?|tml)|aspx?|c(?:fm|gi)|html?|j(?:html|sp)|shtml?|dll|fcgi|rbml|xhtm)

注意:我在这里选择从较频繁到较不频繁的第一个字符排序。但是如果在实践中你注意到例如“dll”是最常见的,你可以改变“d”替代品的位置。

注2:不要认为短模式是一种有效的模式。