Я пытаюсь сформулировать самое короткое из возможных регулярных выражений для проверки, содержит ли маркер параметра (в строке) определенное расширение файла.
Расширения, которые я хотел бы проверить:
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, и поэтому я не лучший в этом.
Вы можете объединить некоторые из них:
aspx?|cfm|f?cgi|dll|s?html?|[jp]html|xhtm|rbml|jsp|php[s4]?
Однако, на мой взгляд, ваше оригинальное регулярное выражение в порядке. Короче не обязательно лучше. Перечисление всех случаев отдельно делает более ясным, что вы делаете. Слияние множества дел затрудняет понимание.
Чтобы построить эффективный шаблон, который начинается с чередования, вам нужно учитывать только первый символ каждой альтернативы. Причина в том, что как только первый символ совпадает, вам не нужно тестировать другую альтернативу. Здесь, если я посчитаю количество вхождений для каждого первого символа в списке, я получу:
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: не верьте, что короткий шаблон является эффективным.