Регулярные выражения

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

Регулярные выражения состоят из специальных метасимволов, которые обозначают разные типы символов и операторов, таких как символы-ограничители и флаги соответствия. Эти метасимволы позволяют создавать сложные образцы, которые могут соответствовать различным ситуациям.

Как использовать регулярные выражения в Ruby?

Ruby предоставляет широкий набор методов для работы с регулярными выражениями. Давайте рассмотрим наиболее используемые методы для работы с регулярными выражениями в Ruby:

  • метод .match - используется для поиска соответствия между регулярным выражением и строкой текста. Он возвращает информацию о соответствии.

# строка, в которой будет осуществляться поиск
string = "hello world"
# регуялрное выражение, в котором мы ищем слово world
regexp = /world/
# результат поиска соответствия
match = regexp.match(string) 
p match # = MatchData("world")
puts match[0] # = world. Результат поиска

попробуем сделать тоже самое, но без соотвествия

string = "hello world"
regexp = /goodbye/
match = regexp.match(string) #  = nil. Ничего не найдено
  • метод .scan - используется для поиска всех соответствий между регулярным выражением и строкой текста. Он возвращает массив со всеми соответствиями.

# строка, в которой будет осуществляться поиск
string = "hello world"
# ищем в строке все совпадения с буквой 'l'
matches = string.scan(/l/)
p matches # = ['l', 'l', 'l']. В строке есть 3 буквы 'l'

попробуем сделать тоже самое, но без соотвествия

# строка, в которой будет осуществляться поиск
string = "hello world"
# ищем в строке все совпадения с буквой 'p'
matches = string.scan(/p/)
p matches # = []. В строке нет буквы 'p'
  • метод .gsub - используется для замены всех соответствий между регулярным выражением и строкой текста на новую строку. Он возвращает новую строку.

# строка, в которой будет осуществляться
string = "hello world"
# заменяем все буквы 'l' на 'L'
new_string = string.gsub(/l/, "L")
# новая измененная строка
puts new_string # = 'heLLo worLd'
# при этом изначальная строка не изменилась
puts string # = 'hello world'
  • метод .sub - используется для замены первого соответствия между регулярным выражением и строкой текста на новую строку. Он возвращает новую строку.

# строка, в которой будет осуществляться
string = "hello world"
# заменяем все буквы 'l' на 'L'
new_string = string.sub(/l/, "L")
# новая измененная строка
puts new_string # = 'heLlo world'. Изменилась первая встречающаяся буква 'l' на 'L', отсальные остались без изменения
# при этом изначальная строка не изменилась
puts string # = 'hello world'

Синтаксис регулярных выражений

Регулярные выражения в Ruby помещаются внутрь символов-ограничителей, которые могут быть различными. Наиболее часто используемыми ограничителями являются косые черты / /, знаки процента %r и фигурные скобки { }.

Например, следующий код демонстрирует использование регулярного выражения, заключенного внутрь символов-ограничителей / /:

string = "hello world"
match = /world/.match(string)
puts match[0]

В качестве другого примера, следующий код демонстрирует использование регулярного выражения, заключенного внутрь символов-ограничителей %r:

string = "hello world"
match = %r{world}.match(string)
puts match[0]

Ruby поддерживает специальные классы символов, которые могут быть использованы в регулярных выражениях для определения определенных типов символов.

Классы символов представляют собой наборы символов, которые могут соответствовать различным типам символов. Например, \d соответствует цифрам, а \w соответствует буквам и цифрам.

Рассмотрим наиболее распространенные классы символов в Ruby:

  • \d - соответствует цифрам от 0 до 9.

# строка, в которой будет осуществляться
string = "r1234g567890d"
# поиск всех цифр
matches = string.scan(/\d/)
p matches # = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
  • \w - соответствует буквам и цифрам.

# строка, в которой будет осуществляться
string = "hello1234world"
# поиск всех цифр и букв
matches = string.scan(/\w/)
p matches # = ["h", "e", "l", "l", "o", "1", "2", "3", "4", "w", "o", "r", "l", "d"]
  • \s - соответствует пробелам, символам табуляции и переводам строк.

# строка, в которой будет осуществляться
string = "hello world"
# поиск всех пробелов
matches = string.scan(/\s/)
p matches # = [" "]
  • . - соответствует любому символу.

# строка, в которой будет осуществляться
string = "hello world"
# поиск всех символов
matches = string.scan(/./)
p matches # = ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]

Операторы сопоставления

Ruby также поддерживает операторы сопоставления, которые могут быть использованы в регулярных выражениях для выполнения специальных операций.

Наиболее распространенными операторами являются:

  • ? - означает "ноль или один", т.е. соответствует элементу, который может присутствовать в тексте один раз или отсутствовать.

string = "colour"
another_string = "color"
# регулярное выражение для поиска 'colour' с возможностью пропустить букву 'u'
regexp = /colou?r/
match = regexp.match(string)
another_match = regexp.match(another_string)
puts another_match[0] # = 'colour'
puts match[0] # = 'color'
  • * - означает "ноль или более", т.е. соответствует элементу, который может присутствовать в тексте ноль или более раз.

string = "heeeello"
# ищем все буквы 'e' или слова состоящие из нескольких 'e' подряд
# а также их отсуствие в тексте вообще
matches = string.scan(/e*/)
# может показаться, что тут у нас ошибка
# но регулярка обходится по буквам в слове, а * означает, что может и не быть буквы 'e'
# Соответственно мы бдем на каждой букве искать либо 1 и более 'e', либо пустую строку
p matches # = ["", "eeee", "", "", "", ""]
  • + - означает "один или более", т.е. соответствует элементу, который может присутствовать в тексте один или более раз.

string = "heeeello"
# ищем все буквы 'e' или слова состоящие из нескольких 'e' подряд
matches = string.scan(/e+/)
p matches # = ["eeee"]
  • [] - используется для определения набора символов, которые могут соответствовать одному элементу.

string = "color"
# ищем все буквы, которые входят в набор между [ и ]
matches = string.scan(/[aeiou]/)
p matches

Задание word_splitter

Возьмите английский текст (не менее 100 слов) и напишите программу, которая будет разбивать его на слова и печатать слова в консоли. Знаки препинания не являются частью слова.

Задание phone_checker

Реализуйте удаление лишних символов при вводе номера телефона в консоли и проверку соответствия номера формату мобильных номеров России. Если введённую строку нельзя привести к формату мобильного номера — выводите сообщение о неверном вводе. Телефон может быть введен не только в формате 79091234567, но и с лишними символами.

Пример ввода номеров и результата вывода программы:

Ввод пользователя в консольВывод программы в консольПримечание

+7 909 123-45-67

79091234567

Символов 11 в номере, код страны 7 — номер верный.

+7 (909) 1234567

79091234567

Символов 11 в номере, код страны 7 — номер верный.

8-905-1234567

79051234567

Символов 11 в номере, первый символ 8 (код выхода на мобильный номер) заменяем на код страны 7 — номер верный.

9-453-1234567

Неверный формат номера

Символов 11 в номере, первый символ после очистки 9, это не 7 и не 8 — формат номера неверный.

8-905-123

Неверный формат номера

Символов 7 в номере — номер неверный.

905-1234567

79051234567

Количество символов 10 после очистки — значит, приводим к формату номера с 7.

8-905-12345672342

Неверный формат номера

Символов в номере больше чем 11 — номер неверный.

Задание replace_diamonds

Реализуйте метод def search_and_replace_diamonds(text, value, placeholder) который будет заменять в переданной строке text всё содержимое скобок <value> и сами скобки на переданную строку в String placeholder, используя регулярные выражения.

Пример:

puts search_and_replace_diamonds('Hello <name> !','name', 'Evgenii') # = Hello Evegenii !

Учитывайте, что <value> может встречаться несколько раз в строке

Last updated