Думаю будет неплохо если я опубликую затрагиваемую мной тему.
Тема: Введение в RegExp
Введение.
Регулярные выражения поддерживаются во многих языках программирования и являются по настоящему мощным инструментом работы с текстом. Я постараюсь рассказать про базовый "Словарь RegExp".
Понимание происходящего в RegExp открывает много новых возможностей для программиста и значительно ускоряет его работу.
Пока я не могу отвечать на такие вопросы как "Как?" и "Почему?" я попробую ответить на вопрос "Что?" возможно это и не интересно, но крепкий фундамент и ответ на вопрос "Что есть регулярные выражения" помогут в дальнейшем понимать суть происходящего.
Знакомство с Регулярными Выражениями
Ни для кого не будет секретом если я скажу что у RegExp есть 2 типа символов
- Специальные символы (метасимволы)
- Символы (литералы)
Для составления регулярных выражений можно воспользоваться сервисом http://myregexp.com/
Итак рассмотрим простые метасимволы которые мы будем использовать практически каждый раз.
Описывать регулярные выражения я буду в символах ‼(19)
Базовые метасимволы RegExp
Начало и конец строки
‼^‼ - означает начало строки (крышка, циркумфлекс)‼$‼ - означает конец строки
Теперь мы можем составить простейший слог ‼^$‼ данное выражение будет искать строки у которых есть начало и сразу же идёт конец
Специфика данных символов заключается в том что они не привязаны к конкретному символу строки, а связанны именно с позицией.
Символьный класс
‼[]‼ - содержимое класса определяет список символов, и подразумевается связка "или" между символами, а не "и" как это происходит вне класса.К примеру можно вести поиск слова "Антон" или "антон" используя символьный класс ‼[Аа]нтон‼
Причём класс не обязательно должен состоять из 2х символов, но в контексте выражения он будет означать именно один символ из множества.
Дополнительно стоит отметить что у Символьного класса существует свои Метасимволы. Символ "-" может записывать интервалы. Так [123456789] и [1-9] будут обозначать одно и тоже. Если же внутри класса символ "-" необходимо использовать в качестве литера его необходимо употреблять сразу после "[".
Любой Символьный класс можно инвертировать метасимволом "^", в начале класса. Так выражение ‼[^Аа]нтон‼ будет искать слово которое не начинается на символы "А" или "а" и заканчивается "нтон", корректным к примеру будет "Онтон" или "кнтон"
Инвертированный класс лучше всего воспринимать как сокращённую запись символьного класса включающего все возможные символы кроме перечисленных.
Один произвольный символ
Метасимвол "." означает совпадение с любым символом. Так если мы ищем конкретную дату но записанную в разных форматах 17-12-1985 или 17.12.1985 или 17/12/1985 то мы можем использовать выражение ‼17.12.1985‼ для поиска нужных дат. Тем ни менее стоит учитывать что в данную выборку попадут и такие фраз 1781221985 поскольку метасимвол "." обозначает любой символКонструкция выбора
Метасимвол "|" обозначает условие "или" и работает вне символьного класса, к конструкции выбора так же относится ещё 2 метасимвола "(" и ")" которые ограничивают область действия конструкции выбора так к примеру ‼А|антон‼ и ‼(А|а)нтон‼ будут иметь абсолютно разное значение в первом случае будет искаться символ "А" в любом месте или слово "антон" в любом месте даже внутри слова, во втором случае будет искаться слова "Антон" или "антон" в любом месте.Конструкция повторения
Иногда случается необходимость поиска повторяющихся символов для этого служат следующие метасимволы- "?" - не более одного символа
- "+" - не менее одного символа
- "*" - любое количество символов даже их отсутствие
Данные метасимволы можно использовать как на определённые символы так и на символьный класс
Также может быть доступна задание интервала повторений. Данный интервал указывается в "{х,у}" так интервал повторения {0, 1} соответствует "?"
Обратные ссылки
В регулярных выражениях можно использовать обратные ссылки. Данное свойство очень полезно для поиска повторяющихся символов в строке ‼([т]*)([о]).+\1\2‼ссылка "\1" обращается к первой скобке, а "\2" ко второй, нумерация скобок идёт последовательно
Экранирование
Данная функция применяется при необходимости использовать метасимвол в качестве обычного литера, или придания литеру особого смысла. Символ используемый для экранирования "\" к примеру для поиска "." в тексте выражение типа ‼.‼ будет бесполезным поскольку данная фраза говорит что необходимо найти любой символ. В таком случае нам необходимо использовать экранирование ‼\.‼ тем самым мы говорим что необходимо искать именно точку.Заключение
Вот собственно и перечислены основные "буквы" регулярных выражений. Осталось только научиться использовать их в нужных местах. Конечно есть множество особенностей в регулярных выражениях с которыми я ещё не успел познакомиться. Но надеюсь что фундамент для дальнейшего развития и понимания регулярных выражений заложен.Для закрепления знаний предлагаю решить простую задачу, каждый сам для себя и обсудить пути её решения.
Также стоит отметить что регулярные выражения всегда ведут себя позитивно, т.е. они ищут присутствие символа, а не его отсутствие. Для полного понимания выражения стоит читать его буквально.
Задание для самоконтроля
Поиск номера телефона заданного формата в тексте, с игнорированием номеров указанных в ""Здравствуйте уважаемые господа, для обратной связи со мной используйте телефон № 8(819)-238-91-28
Здравствуйте уважаемые господа, для обратной связи со мной используйте телефон № +7 819 238 91 28
Здравствуйте уважаемые господа, для обратной связи со мной используйте телефон № +8/819/238/91/28
Здравствуйте уважаемые господа, для обратной связи со мной используйте телефон № 8.(928)*233-91 28 с руско говорящим интерфейсом
Не звоните мне на номер "+7 147 233 87 92" поскольку он более не актуален.
Мои пути решения такие
ОтветитьУдалить1. [^"]\+?[0-9].{0,2}[0-9]{3}.{0,2}[0-9]{3}.[0-9]{2}.[0-9]{2}[^"]
2. [^"]\+?[0-9].{13,18}[0-9][^"]
Как я рассуждал:
1. Поскольку нам нужно исключить номер указанный в "" то говорим что первый символ может быть любым кроме ", затем идёт не обязательный 1 знак +, далее идёт код страны 1 цифра, потом может быть 2 или менее необязательных любых символа, потом 3 цифры, затем снова 2 или менее не обязательных символа, затем ещё 2 цифры, символ, ещё 2 цифры и всё это должно закончиться любым символом кроме как "
2. выражение даёт менее точный результат, но для указанного задания полностью подходит
Номер начинается с любого символа кроме ", за которым идёт не обязательный символ +, затем 1 цифра, далее от 13 до 18 любых символов, которые заканчиваются цифрой, и любым символом кроме ".
Моё решение :)
ОтветитьУдалить[^"](\+?[87].?[\( /][0-9]{3}[\) /][\-\*]?[0-9]{3}[\- /][0-9]{2}[\- /][0-9]{2})[^"]
Вот только я подумал, что требуется выделять только те номера, которые соответсвуют приведенным в задании, т.к. они довольно специфические и не соответсвуют стандартному написания номеров телефонов.
P.S. Если, что код страны может быть трехзначный, а 8 (без плюса) не является кодом страны.
P.P.S Coffe'n'Code
Т.е. Ты решил, перечислить всю последовательность символов, которые могут встретиться в номере?
ОтветитьУдалитьДа кстати интересный манёвр с любым не обязательным символом после кода страны.
И ещё альтернатива [\-\*] была бы [-*] поскольку внутри символьного класса не требуется экранирование "*" (это обычный литерал) а что бы использовать "-" в качестве литерала её необходимо указывать сразу после "["
В общем точность твоего выражения выше чем у меня :).
P.S. ага про код страны согласен но хотелось использовать + как не обязательный символ :).
P.P.S. тему сейчас исправлю. Спасибо за поправку.