Первое наблюдение: чтение регулярного выражения - это кошмар. Он взывает к Perl's / x mode.
Второе наблюдение: в выражении есть много, много и много захватывающих скобок (42, если я правильно считаю; и 42, конечно, «Ответ жизни, вселенной и всему» - см. Дуглас Адамс "Руководство по путешествию автостопом по Галактике", если вам нужно, что объяснил).
Bill the Lizard отмечает, что вы используете '(-)?( )?
' несколько раз. В этом нет очевидного преимущества по сравнению с '-? ?
' или, возможно, '[- ]?
', если только вы действительно не намерены захватить фактическую пунктуацию отдельно (но есть так много захватывающих скобок, которые вырабатывают '$ n * Использовать 1009 * предметов было бы сложно).
Итак, давайте попробуем отредактировать копию вашей однострочной:
( |^|>)
(
((((((\+|00)(31|32)( )?(\(0\))?)|0)([0-9]{2})(-)?( )?)?)([0-9]{7})) |
((((((\+|00)(31|32)( )?(\(0\))?)|0)([0-9]{3})(-)?( )?)?)([0-9]{6})) |
((((((\+|00)(31|32)( )?(\(0\))?)|0)([0-9]{1})(-)?( )?)?)([0-9]{8}))
)
( |$|<)
ОК - теперь мы можем видеть регулярную структуру вашего регулярного выражения.
Отсюда возможно гораздо больше анализа. Да, в регулярном выражении могут быть значительные улучшения. Первый, очевидный, один заключается в том, чтобы извлечь часть международного префикса и применить ее один раз (по желанию или требовать начальный ноль), а затем применить национальные правила.
( |^|>)
(
(((\+|00)(31|32)( )?(\(0\))?)|0)
(((([0-9]{2})(-)?( )?)?)([0-9]{7})) |
(((([0-9]{3})(-)?( )?)?)([0-9]{6})) |
(((([0-9]{1})(-)?( )?)?)([0-9]{8}))
)
( |$|<)
Затем мы можем упростить знаки препинания, как отмечалось выше, удалить некоторые вероятные избыточные скобки и улучшить распознаватель кода страны:
( |^|>)
(
(((\+|00)3[12] ?(\(0\))?)|0)
(((([0-9]{2})-? ?)?)[0-9]{7}) |
(((([0-9]{3})-? ?)?)[0-9]{6}) |
(((([0-9]{1})-? ?)?)[0-9]{8})
)
( |$|<)
Мы можем заметить, что регулярное выражение не обеспечивает соблюдение правил для кодов мобильных телефонов (поэтому оно не настаивает на том, чтобы за «06» следовали, например, 8 цифр). Кажется также, что допускается необязательное использование 1, 2 или 3-значного кода обмена, даже с международным префиксом - вероятно, не тем, что вы имели в виду, а исправление, которое удаляет еще несколько скобок. После этого мы можем удалить еще несколько скобок, что приведет к:
( |^|>)
(
(((\+|00)3[12] ?(\(0\))?)|0) # International prefix or leading zero
([0-9]{2}-? ?[0-9]{7}) | # xx-xxxxxxx
([0-9]{3}-? ?[0-9]{6}) | # xxx-xxxxxx
([0-9]{1}-? ?[0-9]{8}) # x-xxxxxxxx
)
( |$|<)
И вы можете продолжить дальнейшую оптимизацию, я надеюсь.