Привет!
Я много работаю с VoIP-сетями. С коммерческим оборудованием, конечно тоже, но и очень много с OpenSource (статья пишется в контексте использования Asterisk PBX).
В телефонии часто возникает простая задача, разделить маршруты на определённые направления. Ну например, направить вызовы на городские номера в сторону оператора 1, МГ — в сторону оператора 2, МН — в сторону оператора 3.
Задача, в общем-то тривиальная, и реализуется на Asterisk легко:
;Местная городская связь: 7 знаков (в разных регионах РФ от 3-х до 7-ми знаков), и номера экстренных служб.
exten => _0X,1,dial(SIP/itsp1/${EXTEN})
exten => _0XX,1,dial(SIP/itsp1/${EXTEN})
exten => _XXXXXXX,1,dial(SIP/itsp1/${EXTEN})
;Междугородняя и мобильная связь: код выхода на МГ связь (в РФ - "8") + 10 знаков.
exten => _8[348]XXXXXXXXX,1,dial(SIP/itsp2/${EXTEN})
exten => _89XXXXXXXXX,1,dial(SIP/itsp2/${EXTEN})
;Международная связь: код выхода на МН связь (в РФ - "810") + номер телефона в международном формате.
exten => _810X.,1,dial(SIP/itsp3/${EXTEN})
Однако иногда возникает необходимость предоставить абоненту доступ только к мобильным телефонам его области, и здесь простым "_89XXXXXXXXX" не отделаешься.
От переводчика
Это перевод небольшой заметки, написанной вчера
Lea Verou, в ней предлагается интересная, хотя и не новая техника для решения повседневных задач.
Информация в статье касается
ECMAScript, но может использоваться и в других RegExp Движках (хотя и есть вероятность, что там есть более подходящее решение).
Если примеры кажутся вам сложными, рекомендую играть с ними в консоли, по мере прочтения. И Заранее прощу прочтение за пугающее название.
Статья
Если вы какое-то время используете регулярные выражения, то наверняка вы сталкивались с разными вариантами следующих задач:
- Пересечение:«Что-то, что совпадает с шаблоном А и шаблоном Б»
Например: Пароль, минимум 6 символов, в котором хотя бы одна цифра, хотя бы одна буква, и хотя бы один специальный символ
- Исключение: «Я хочу что-то, что совпадает с шаблоном А, но не совпадает с шаблоном Б»
Например: Любое целое число, которое не делится на 50
- Отрицание: Все. Что не совпадает с шаблоном А
Например: Строка, которая не содержит в себе слово «Foo»
Regular Expressions For All (REFA)
Основная идея
Существует множество систем для поиска подстрок отвечающих определенной маске. К сожалению они теряют свою мощь как только приходится учитывать многие факторы. Конструкции становятся громозкими, непонятными и трудноподдерживающими.
Именно для этого я попытался создать аналог – REFA. Регулярные выражения для всех.
Его идея в следующем. Как только регулярное выражение перестает быть очевидным – разбить его на два. Оптимизатор при возможности все равно сведет его в одно, таким образом в скорости потерь не будет, но зато код станет яснее.
В книге Дж.Фридла «Регулярные выражения» я наткнулся на то, что автор намекает не использовать компиляцию регулярных выражений для повседневных случаев и использовать только для критических, когда крайне важна скорость выполнения, особенно если выражение работает с большим объемом текста.
Аналогичное мнение наблюдается и в
msdn.
Но так ли это?
Задача выделения из потока символов определенных лексем является весьма распространенной. Часто ее решают с помощью лексических анализаторов, конфигурируемых регулярными выражениями. Многие анализаторы построены по принципу генерации программного кода, который в свою очередь реализует логику регулярных выражений. Фактически, это компиляция языка регулярных выражений в код языка программирования.
Например,
flex — это один из таких анализаторов. Старый, но проверенный годами.
Я много пользовался flex'ом, он имеет и плохие и хорошие стороны, но по большому счету, жаловаться не приходилось.
Но вчера наткнулся на интересный проект —
re2c. По сути, на этой штуке можно писать лексические анализаторы прямо на коленке за несколько минут.
В общем, наверное, как и другой любой начинающий JavaScript прогрммист (2 года назад), мне хотелось все реализовать своими руками. Так возникло
ужасающее очень быстрое регулярное выражение из 280 символов.
Немного истории
Приблизительно полтора года назад, я узнал о библиотеке
yass, которая была самым быстрым инструментом для поиска DOM элементов в JavaScript по CSS селекторам (
ссылка на тесты).
И тут у меня возник ужасный интерес. Я захотел придумать способ, который будет еще быстрее. В то время я как раз читал книгу «Регулярные выражения Библиотека программиста» второе издание от Дж. Фридла. И вот… Это было лето, я еще был студентом и у меня была масса времени. Работа закипела…
20 февраля 2011, 22:38
94
Часть 1: метасимволы внутри и вне символьных классов.
В этой части я хотел бы рассказать про то, как же работают движки регулярных выражений, почему некоторые люди считают, что регулярные выражения очень медленные, и почему авторы многих движков не соблюдают стандарт POSIX.
Вместо вступления
Все, кто хоть раз писал программы, знают, что на свете есть такое чудо, как регулярные выражения. Некоторые не могут пройти без них ни шагу, некоторые боятся их как огня, но представить современный язык программирования без регулярных выражений крайне сложно.
Что бывает, когда начинающий программист в первый раз узнает про регулярные выражения? Чаще всего первое знакомство с ними происходит методом «научного тыка», поскольку ни знаний в соотвествующей области, ни понимания «как это работает» обычно на данном этапе у человека нет. Почему так происходит?
17 января 2011, 18:15
119
Регулярное выражение для валидации номера телефона:
^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$
Ориентировано на российские мобильные + городские с кодом из 3 цифр (например, Москва).
26 декабря 2010, 13:50
218