Выражение выглядит в целом хорошо, как уже упоминали другие, оно может быть немного многословным со всеми {0,1}
вместо ?
и (?:
вместо применения RegexOptions.ExplicitCapture
. Но это не должно замедлять выражение. Они только улучшают читаемость.
Что может вызывать медлительность, так это то, что в выражении есть много опций обратного отслеживания, сделанных как расширенный месяц, так и. необязательный. Интересно, что произойдет, если вы измените выражение, чтобы применить только необязательные. один раз, после названия месяца, и что произойдет, если вы сделаете название месяца жадной группой ((?>pattern)
невыраженное (или «жадное») подвыражение.)
Так что:
(jan(?:uary){0,1}\.{0,1}|feb(?:ruary){0,1}\.{0,1}|mar(?:ch){0,1}\.{0,1}|apr(?:il){0,1}\.{0,1}|may\.{0,1}|jun(?:e){0,1}\.{0,1}|jul(?:y){0,1}\.{0,1}|aug(?:ust){0,1}\.{0,1}|sep(?:tember){0,1}\.{0,1}|oct(?:ober){0,1}\.{0,1}|nov(?:ember){0,1}\.{0,1}|dec(?:ember){0,1}\.{0,1})\s+(\d{2,4}))
станет:
(?>jan(uary)?|feb(ruary)?|mar(ch)?|apr(il)?|may|june?|july?|aug(ust)?|sep(tember)?|oct(ober)?|nov(ember)?|dec(ember)?)\.?\s+(\d{2,4}))
Мало того, что это намного короче, я ожидаю, что это будет быстрее.
А потом в начале есть часть выражения, которая на самом деле не имеет смысла для меня. (?:(\d{1,4})- /.- /.)
Либо что-то потеряно при форматировании, либо это никуда не поможет.
\ d {1,4} будет иметь смысл для года или любой другой части даты, но - /.- /.
после этого вообще не имеет смысла. Я думаю, что вы имели в виду что-то вроде:
\d{1,4}[- /.]\d{1,2}[- /.]\d{1,2}
Или что-то в этом районе. В существующем состоянии он собирает мусор, вероятно, не ускоряя процесс сопоставления.
В конце я согласен с Aliostad, что вам, вероятно, лучше попытаться найти менее точный шаблон для поиска первоначальных кандидатов, а затем сузить результаты, используя либо DateTime.TryParseExact, либо с дополнительным набором выражений.
Вместо создания «глобального» выражения для поиска кандидатов, вы можете использовать множество точных выражений. Вы увидите, что с Regex часто дешевле запускать несколько точных выражений для большого ввода, чем запускать одно выражение с большим количеством символов | и ?.
Так что разбиение поиска на несколько очень точных выражений может привести к гораздо более высокой производительности, это может быть началом:
\b\d{1,2}[- .\\/]\d{1,2}[- .\\/](\d{2}|\d{4})\b
\b((jan|feb|mar|apr|jun|jul|aug|sep|oct|nov|dec)(.|[a-z]{0,10})|\d{1,2})[- .\\/,]\d{1,2}[- .\\/,](\d{2}|\d{4})\b
Как вы можете видеть, все необязательные группы были удалены из этих выражений, что значительно ускорило их запуск. Я также удалил точное написание из названий месяцев, так как вы, вероятно, хотите принять «сентябрь», а также «сентябрь» и «сентябрь»
Разбиение шаблона также улучшает читабельность:).
Последний совет: ограничьте количество возможных символов, которые нужно откатить назад, ограничив такие вещи, как \ s +, вы редко хотите, чтобы совпадало 20 000 пробелов, но если они есть в вашем исходном документе, он попытается сопоставить их. \ s {1,20} обычно достаточно и ограничивает способность двигателей пытаться найти совпадение там, где его нет.