2014-11-02 3 views
0

Я пытаюсь сформулировать кратчайшее регулярное выражение для проверки того, содержит ли токен параметра (в строке) определенное расширение файла.Регулярное выражение: Ограниченные расширения

Расширения Я хотел бы проверить, являются:

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, и поэтому я не лучший в этом.

+1

Что не так с 'in_array ($ ext, explode (',', 'asp, aspx, cfm, cgi, fcgi, dll, htm, html, shtm, shtml, jhtml, phtml, xhtm, rbml, jsp, php , ПГПС, php4')) '? – Gumbo

+0

** ## WHY ## ?? ** Regex не зависит от ** SHORT ** и ** LONG **, просто для работы с Regex важна производительность. действительно, я предпочитаю 'asp | aspx | cfm | cgi | fcgi | dll | htm | html | shtm | shtml | jhtml | phtml | xhtm | rbml | jsp | php | phps | php4', потому что это не двусмысленно –

+0

@Gumbo - ничего плохого в этом, но нет ничего плохого в обучении. :) –

ответ

3

Вы можете объединить некоторые из них:

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

Однако, на мой взгляд оригинал регулярное выражение хорошо. Короче не обязательно лучше. Перечисление всех случаев отдельно делает более понятным, что вы делаете. Слияние многих случаев затрудняет понимание.

+0

Истинно, я могу разобраться с ними. Я просто подумал, что может быть хорошей идеей присоединиться к ним в то время, и, как я уже упоминал в своем комментарии, никакого вреда в обучении. Но ты прав. :) –

+0

Принимая это - это похоже на то, что я хотел. Даже если я выхожу на место, он отвечает на вопрос. :) –

+0

@Barmar этот ответ будет соответствовать строке, содержащей 'jhtm',' phtm' и 'xhtml', поскольку он просто должен соответствовать' htm'.Я был немного удивлен вашей критикой другого ответа. – hcoat

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».

Note2: не верьте, что короткий образец является эффективным образцом.

+0

Мне это очень нравится - это здорово учиться. +1 –

Смежные вопросы