Если нельзя, но очень хочется, то нужно обязательно и ничего в мире не стоит того, чтобы делать из этого проблему!


Интересна Java? Кликай по ссылке и изучай!
Если тебе полезно что-то из того, чем я делюсь в своем блоге - можешь поделиться своими деньгами со мной.
с пожеланием
столько времени читатели провели на блоге - 
сейчас онлайн - 

суббота, 24 марта 2012 г.

Регулярные выражения - это просто

Начал читать книгу "Регулярные выражения" автора Дж. Фридла. Просто о сложном. Много водички, а потому я буду вести в своем блоге конспект лекций.

Мне понравилось что сказал автор про ругулярные выражения:

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

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

Мне очень понравился этот тул и сегодня я его рекомендую для экспериментов. А изучать регекспы мы будем на практике. И вот тот текст, который сегодня будем использовать для примеров. Текст песни "Звезда по имени Солнце" Виктора Цоя. Надеюсь никто не против, я очень люблю эту песню.

Белый снег, серый лед
На растрескавшейся земле
Одеялом лоскутным на ней
Город в дорожной петле


А над городом плывут облака
Закрывая небесный свет
А над городом желтый дым
Городу две тысячи лет
Прожитых под светом звезды по имени Солнце


И две тысячи лет война -
Война без особых причин
Война - дело молодых
Лекарство против морщин


Красная-красная кровь
Через час уже просто земля
Через два на ней цветы и трава
Через три она снова жива
И согрета лучами звезды по имени Солнце


И мы знаем, что так было всегда
Что судьбою был больше любим, -
Кто живет по законам другим
И кому умирать молодым


Он не помнит слова "Да" и слова "Нет"
Он не помнит ни чинов ни имен
И способен дотянуться до звезд
Не считая что это сон
И упасть опаленный звездой по имени Солнце


Предлагаю ее скопипастить в поле для текста, где написано 'Welcome to RegExr 0.3b, an intuitive...' Лишние пробелы между куплетами можно удалить, чтобы весь текст был перед глазами.

В поле регулярки введем однин символ и увидим как тулза красиво найдет все места, в которых символ встречается.


Если вводить простой текст (а символы его составляющие называются литералами), то тулза ничего необычного из себя не представляет - тупо поиск текст. Но магия начинается с так называемыми метасимволами - спецсимволами которые задают режимы поиска.

Вот ты хочешь поискать все файлы на винчестере с расширением 'txt' - как будешь об этом просить операционку? Ну как-то так - '*.txt'. Вот тут '.txt' - литерал, а '*' - метасимвол. Но это вовсе не регулярные выражения - там немного другие правила. Но принцип тот же.

Попробуй поиграйся с поиском простого текста. Учти, что символы [ ] \ / ^ $ . | ? * + ( ) { } являются метасимволами и пока их не стоит использовать.

Наигрался? Пойдем дальше. Начнем с метасимвола ˹^˼ (крышка, циркумфлекс). Он указывает на начало строки. Попробуй введи в качестве запроса литерал ˹Не˼ - найдешь тем самым два места (как ты уже наверное понял тут все чувствительно к регистру и ˹abc˼ != ˹Abc˼).

Кстати, ты заметил, что весь текст я беру в 'одинарные кавычки', а регулярки ˹угловые кавычки˼. Эту идею так же использует автор книги. Чтобы не запутаться. И еще, на будущее, символ пробела в регулярке будет отображаться точкой ˹˼.


Теперь, чтобы второй вариант (в начале строки), надо указать в качестве запроса ˹^Не˼.

Попробуй. Попробовал? Супер!

Автор книги призывает воспринимать этот нехитрый запрос не так:
˹^Не˼ совпадает, если строка начинается с 'Не'
но так:
˹^Не˼ совпадает, если мы находимся в начале строки, после которого сразу же следует символ 'Н', после которого сразу же следует символ 'е'.
То есть все регекспы стоит воспринимать буквально - так легче будет читать их в будущем.

Идем дальше, если есть метасимвол отвечающий за начало строки, то есть метасимвол отвечающий за конец строки. Вот он ˹$˼

Попробуй из запроса ˹ка˼ совпадающего в двух строках сделай так, чтобы остался только первый.


Вероятно у тебя получилось так ˹ка$˼ - и это правильный ответ. Опять же понимать такой запрос надо буквально:
˹ка$˼ совпадает, если после символа 'к' сразу же идет символ 'а', после которого сразу же следует конец строки.
Хотя по факту получается:
˹ка$˼ совпадает, во всех строках, которые заканчиваются на 'ка'.
это не одно и то же - позже у тебя будет возможность в этом убедиться. 

Несколько вопросов на домашку:
  1. C чем совпадет ˹^$˼?  А как стоит прочитать эту регулярку?
  2. C чем совпадет ˹^˼? А как стоит прочитать эту регулярку?
  3. C чем совпадет ˹$˼? А как стоит прочитать эту регулярку?
  4. C чем совпадет ˹^Городу две тысячи лет$˼? А как стоит прочитать эту регулярку? 
  5. А что будет если написать ˹$^˼? 
 Еще один весьма интересный метасимвол -  ˹.˼ - обыкновенная точка. Она указывает на один произвольный символ. Например попробуй на нашем исходном тексте запроси ˹а.а˼


Количество точек может быть любым. Попробуй ˹а..а˼


Располагаться они могут в любом месте (до литералов, после или между).  Попробуй ˹а...а........˼


Но тут если добавить еще одну точку в конец выражения ˹а...а........˼ - оно будет совпадать только с одним из вариантов. Подумай почему так получается?

Я использовал в качестве литерала только один или два символа, но литералом может быть и целое предложение. Например такой запрос ˹......... .......зве....по имени Солнце˼


Будь внимателен с точками, потому как точка - это абсолютно любой символ и если ты захочешь выбрать из текста все даты '27.11.2004' '27-11-2004' и '27/11/2004' то запросом ˹27.11.04˼ ты выберешь так же и чей-то номер телефона '2771132004' это частая ошибка новичков.

Хорошо, а если я хочу использовать метасимвол как литерал? Все просто - перед ним тогда стоит поставить метасимвол ˹\˼ - обратная косая черта экранирует следующий за ней символ. То есть ˹27\.11\.04˼ совпадет только с '27.11.2004'

На сегодня все. В следующий раз разберемся с символьными классами, но чтобы ты не скучал вот тебе пару примеров из следующего поста:
˹бы[лх]˼
˹о[лср]о˼
˹е[а-я]•˼  (напомню, что ˹˼ - это пробел)
˹е[абв]˼ 
˹[-ая]˼
˹[а-вэ-я]л˼
˹[к-ну]т˼
˹[а..]с˼
˹[а-я][к-н]˼

Приятных экспериментов!

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

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