3 способа использования групп захвата Regexp с обратными ссылками в Ruby
Использование групп захвата для управления строками в Ruby
Прежде, чем начать
Позвольте мне представить здесь платформу, которая помогла мне изучить большую часть моих знаний о Ruby. Действительно, Pluralsight - потрясающая платформа.
С 50+ курсами, которые охватывают различные темы по Ruby и Ruby on Rails, это лучший способ поднять свои знания на новый уровень!
Попробуйте бесплатно 👇😉
Спасибо за уделенное время!
Быстрое напоминание о 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>
для обратной ссылки на именованную группу в шаблоне, переданном в качестве первого аргумента.
Заключение
Смешивание групп захвата и обратных ссылок - мощный инструмент, который может улучшить читаемость вашего кода. Однако рекомендуется аннотировать группы захвата с помощью индексов обратных ссылок, чтобы обеспечить удобочитаемость вашего регулярного выражения.
Вуаля!