3 способа использования групп захвата Regexp с обратными ссылками в Ruby

Использование групп захвата для управления строками в Ruby

Прежде, чем начать

Позвольте мне представить здесь платформу, которая помогла мне изучить большую часть моих знаний о Ruby. Действительно, Pluralsight - потрясающая платформа.

С 50+ курсами, которые охватывают различные темы по Ruby и Ruby on Rails, это лучший способ поднять свои знания на новый уровень!

Попробуйте бесплатно 👇😉



Pluralsight | Бесплатная личная пробная версия
Подробнее о бесплатных пробных версиях Pluralsight. pluralsight.pxf.io



Спасибо за уделенное время!

Быстрое напоминание о Regexp и группах захвата

В Ruby логика регулярных выражений заключена в класс Regexp. Есть 3 способа создать экземпляр Regexp

Итак, следующий вопрос: как сопоставить это Regexp с String?

Класс MatchData

Класс Regexp предоставляет метод Regexp#match, который принимает aString для проверки в качестве параметра

Метод Regexp#match возвращает экземпляр MatchData. Класс MatchData инкапсулирует все результаты сопоставления с образцом. Я предлагаю вам прочитать официальную документацию, чтобы узнать, что вы можете делать с экземпляром MatchData. Например, вы можете использовать MatchData#to_a для итерации результатов.

Оператор сопоставления с образцом = ~

Чтобы упростить использование регулярных выражений, Ruby предоставляет синтаксический сахар =~. Этот оператор сопоставляет Regexp с String

Обратите внимание, что все магические переменные установлены, потому что =~operator создает экземпляр MatchData, если regexp совпадает с String.

Группы захвата

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

if /(hello) (world)/ =~ "hello world"
  puts "#{$2} #{$1}" # => "world hello"
end

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

Именованные захваты

Именованная функция захвата, когда она используется с оператором =~, имеет мощный механизм, который автоматически назначает результат соответствующей группы в локальную переменную, используя имя, присвоенное группе, в регулярном выражении.

Именованная функция захвата также доступна с методом Regexp#match. Основное отличие состоит в том, что переменная не создается. Действительно, именованные захваты доступны в возвращенном экземпляре MatchData с помощью метода MatchData#[].

Группы захвата и обратные ссылки

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

/(hello) \1/ =~ "hello hello" # => 0

Здесь \1 относится к первой объявленной группе захвата (hello). Если вы объявляете две группы захвата, вы можете ссылаться на каждую из этих групп, используя \1 и \2.

Группы захвата и обратные ссылки - это просто и весело. Но Ruby позволяет пойти еще дальше. Действительно, Ruby позволяет вам получать доступ к группам захвата вне регулярного выражения, используя обратные ссылки. Давайте рассмотрим 3 примера, чтобы лучше познакомиться с этой концепцией.

Использование обратных ссылок в Ruby

Здесь вы увидите, как Ruby использует спецификацию регулярных выражений для элегантного расширения класса String.

String # [] метод

Здесь мы видим, что, чтобы избежать перезаписи html в нашем регулярном выражении, мы используем \1 обратную ссылку на первую группу захвата (html). Этот шаблон помогает нам избежать избыточности в нашем регулярном выражении.

⚠️ Этот метод в основном используется, чтобы избежать избыточности и улучшить читаемость вашего регулярного выражения. Но когда вам приходится иметь дело с несколькими группами захвата, использование обратных ссылок может быстро сделать ваше регулярное выражение нечитаемым. Вот почему рекомендуется аннотировать группы захвата их индексами обратных ссылок, чтобы поддерживать удобочитаемость вашего регулярного выражения \1 : (html), \2 : (head) и т. Д.

String # метод gsub

Здесь to_https метод преобразует http URL в https. Для этого мы используем метод gsub с аргументами:

  • регулярное выражение, представляющее заменяемую подстроку - оно включает http ((http)) и исключает следующие s ((?!s))
  • заменяющая строка с обратной ссылкой на первую группу захвата (http)

Это демонстрирует заботу Ruby о разработчиках. Действительно, в методе String#gsub замещающая строка может включать обратные ссылки на группы захвата в регулярном выражении!

Кстати, загляните в официальную документацию Ruby, если вы не знакомы с концепцией отрицательного просмотра (?!)

Обратные ссылки на именованные группы

Здесь мы воспроизводим то же поведение, что и в предыдущем примере. Единственное изменение состоит в том, что мы используем именованные группы вместо групп захвата. Итак, в заменяющей подстроке мы используем \k, за которым следует метка именованной группы между шевронами \k<scheme> для обратной ссылки на именованную группу в шаблоне, переданном в качестве первого аргумента.

Заключение

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

Вуаля!