вторник, 22 сентября 2009 г.

Регулярные Выражения. Продолжение

И так в своём предыдущем посте я уже описывал базовый синтаксис регулярных выражений, и этого достаточно для решения простых задач. Но повседневные задачи не всегда бывают простыми. Поэтому требуется расширения знаний в этой области. Поскольку RegExp действительно мощное средство, и существует ряд задач которые без его использования являются очень громоздкими и не элегантными.
Итак давайте приступим.

Не сохраняющие круглые скобки
Я уже рассказывал, о обратных ссылках, так вот помимо ссылки, данная конструкция, позволяет сохранить значение в скобках, и пользоваться этим значением в программах.
Но бывают случаи когда группирующие круглые скобки используются только для группировки и они могут быть не обязательными т.е. к скобке применяется квантификатор ‼?‼, в таком случае было бы разумней использовать не сохраняющие круглые скобки, которые игнорируются, и не приведут в заблуждение людей которые будут читать регулярное выражение после вас.
Конструкция данных группирующих скобок будет следующей ‼(?:)‼

Символы пропуски
Стоит отметить что для нашего удобства в Регулярных выражениях существуют метасимволы пропусков, поскольку выражение типа ‼( )‼ достаточно сложно воспринимается, неизвестно что там "пробелы" или "таб".
Для обозначения символа "таб" принято использовать метасимвол ‼\t‼
Для обозначения символа "новой строки" используется ‼\n‼
Для обозначения символа "возврат курсора" используется ‼\r‼
Также существует общий для всех пропусков метасимвол ‼\s‼ - целый символьный класс, который включает в себя "пробел", "Таб", "символы новой строки", "возврат курсора"

Другие символьные классы
Стоит отметить также и другие символьные классы которые обозначаются метасимволами, выше уже приводился символьный класс пропусков обозначаемый ‼\s‼.

К другим символьным классам относятся:
  • ‼\S‼ в него входят все символы за исключением перечисленных в ‼\s‼
  • ‼\w‼ символьный класс который можно записать в виде ‼[0-9a-zA-Z_]‼, данный класс можно исользовать для поиска слова ‼\w+‼
  • ‼\W‼ в него входят все мисволы за исключением перечисленных в ‼\w‼
  • ‼\d‼ класс цифр ‼[0-9]‼
  • ‼\D‼ всё что не относиться к цифрам.
Границы слова
В предыдущем посте я рассказывал о метасимволах, начала и конца строки ‼^$‼, в некоторых диалектах существует метасимвол начала и конца слова, записывается он в виде ‼\b‼

Позиционные проверки
Существует два вида позитивных позиционных проверок, опережающая и ретроспективная, обе проверки на ищут совпадения по выражению, а проверяют за или перед каким символом находится совпадение.
Также существует два вида негативных позиционных проверок, обе они считаются успешными если совпадений нет.

Давайте рассмотрим пример у нас есть фраза "Антон Дегтярёв", и мы имеем выражение ‼Дегтярёв‼, в обычном сулчае выражение нам даст совпадение на слове "Дегтярев", а вот контексте опережающей проверки выражение вида ‼(?=Дегтярев)‼ вернёт нам "пробел", т.е. символ перед которым следует слово "Дегтярев".

Данный инструмент очень полезен. К примеру у нас есть некоторый текст в котором встречаются слова "Дегтярев Дегтяревой Дегтяревым Дегтяревых Дегтярев" нам требуется найти часть слова "Дегтярев", например "Дегтя", но только в словах "Дегтярев", регулярное выражение ‼Дегтя‼ будет совпадать во всех указанных словах. Для решения данной задачи как раз подходит опережающая проверка выражение ‼(?=Дегтярев(\s|$))Дегтя‼ будет соответствовать условию задачи и уже не совпадёт в ненужных словах. Также вырожением можно записать и в другом виде, используя метосимвол начала и конца слова. Выражение будет читаться так:
Найти слово "Дегтя", во всех словах "Дегтярев" за которыми следует символ пропуска или конец строки.

И так:
  • Позитивная опережающая проверка записывается выражением ‼(?=)‼ и означает, что выражение в скобках должно совпадать справа
  • Позитивная ретроспективная проверка записывается выражением ‼(?<=)‼ и означает, что выражение в скобках должно совпадать слева

  • Негативная опережающая проверка записывается выражением ‼(?!)‼ и означает, что выражение в скобках не может совпадать справа

  • Негативная ретроспективная проверка записывается выражением ‼(?< !)‼, что означает выражение в скобках не может совпадать слева.

Если использовать предыдущий пример с ретроспективной проверкой, для фразы "Дегтярев Дегтяревой Дегтяревым Дегтяревых Дегтярев" и выражения ‼(?<=Дегтярев(\s|$))Дегтя‼ совпадения будет только одно в слове "Дегтяревой" А само выражение будет читаться так: найти слово "Дегтя", которое следует за словом "Дегтярев", за которым сразу же идёт символ пропуска или конец строки. Модификаторы регулярных выражений В регулярных выражениях существует такое понятие как модификаторы, они являются очень полезными, поскольку сокращают запись выражения. Модификаторы не являются частью регулярных выражений, это части синтаксической оболочки, и указывают как именно выражение, должно обрабатываться.
  • Модификатор "i" позволяет регулярному выражению искать совпадения без учёта регистра символов. (В Java данный модификатор записывается как Pattern.CASE_INSENSITIVE)
  • Модификатор "g" позволяет выполнять глобальный поиск и не останавливаться на первом совпадении
  • Модификатор "x" позволяет записывать выражение в свободной форме
А теперь разминка для мозгов: Существует некоторое число, его необходимо разбить на разряды. Тип разделителя не имеет значения. Ну или хотя бы написать выражения что бы совпадения были в нужных местах.
Я для данной задачи использовал позитивную и негативную опережающие проверки. Варианты решения жду в комментах. Число пусть будет 1005565896

Комментариев нет:

Отправить комментарий