Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
3.7. Обратные ссылки
Каждая заключенная в круглые скобки часть регулярного выражения является отдельным соответствием. Они нумеруются, и есть несколько способов сослаться на такие части по номерам. Сначала рассмотрим традиционный «некрасивый» способ.
Сослаться на группы можно с помощью глобальных переменных
$1$2str = "а123b45с678"if /(ad+)(bd+)(cd+)/ =~ str puts "Частичные соответствия: '#$1', '#$2', '#$3'" # Печатается: Частичные соответствия: 'а123', 'b45', 'c768'endЭти переменные нельзя использовать в подставляемой строке в методах
subgsubstr = "а123b45с678"str.sub(/(ad+)(bd+)(cd+)/, "1st=#$1, 2nd=#$2, 3rd=#$3")# "1st=, 2nd=, 3rd="Почему такая конструкция не работает? Потому что аргументы
subsubstr = "а123b45с678"s2 = "1st=#$1, 2nd=#$2, 3rd=#$3"reg = /(ad+)(bd+)(cd+)/str.sub(reg,s2)# "1st=, 2nd=, 3rd="Отсюда совершенно понятно, что значения
$1$2$3В такой ситуации на помощь приходят специальные коды
12str = "а123b45с678"str.sub(/(ad+)(bd+)(cd+)/, '1st=1, 2nd=2, 3rd=3')# "1st=a123, 2nd=b45, 3rd=c768"Обратите внимание на одиночные (твердые) кавычки в предыдущем примере. Если бы мы воспользовались двойными (мягкими) кавычками, не приняв никаких мер предосторожности, то элементы, которым предшествует обратная косая черта, были бы интерпретированы как восьмеричные числа:
str = "а123b45с678"str.sub(/(ad+)(bd+)(cd+)/, "1st=1, 2nd=2, 3rd=3")# "1st= 01, 2nd= 02, 3rd= 03"Обойти эту неприятность можно за счет двойного экранирования:
str = "а123b45с678"str.sub(/(ad+)(bd+)(cd+)/, "1st=\1, 2nd=\2, 3rd=\3")# "1st=a123, 2nd=b45, 3rd=c678"Допустима и блочная форма подстановки, в которой можно использовать глобальные переменные:
str = "а123b45с678"str.sub(/(ad+)(bd+)(cd+)/) { "1st=#$1, 2nd=#$2, 3rd=#$3" }# "1st=a123, 2nd=b45, 3rd=c678"При таком применении блока числа с обратной косой чертой нельзя использовать ни в двойных, ни в одиночных кавычках. Если вы немного поразмыслите, то поймете, что это разумно.
Упомяну попутно о том, что существуют незапоминаемые группы (noncapturing groups). Иногда при составлении регулярного выражения нужно сгруппировать символы, но чему будет соответствовать в конечном счете такая группа, несущественно. На этот случай и предусмотрены незапоминаемые группы, описываемые синтаксической конструкцией
(?:...)str = "а123b45с678"str.sub(/(ad+)(?:bd+)(cd+)/, "1st=\1, 2nd=\2, 3rd=\3")# "1st=a123, 2nd=c678, 3rd="В предыдущем примере вторая группа не запоминается, поэтому та группа, которая должна была бы быть третьей, становится второй.
Лично мне не нравится ни одна из двух нотаций (
1$1Метод класса
Regexp.last_matchMatchDatamatchОбращаться к объекту
MatchDatapat = /(. + [aiu])(.+[aiu])(.+[aiu])(.+[aiu])/i# refs = pat.match("Fujiyama")# refs is now: ["Fujiyama","Fu","ji","ya","ma"]x = refs[1]y = refs[2..3]refs.to_a.each {|x| print "#{x}n"}Отметим, что объект
refseachto_aЕсть и другие способы нахождения сопоставленной подстроки внутри исходной строки. Методы
beginendstr = "alpha beta gamma delta epsilon"# 0....5....0....5....0....5....# (для удобства подсчета)pat = /(b[^ ]+ )(g[^ ]+ )(d[^ ]+ )/# Три слова, каждое из которых представляет собой отдельное соответствие.refs = pat.match(str)# "beta "p1 = refs.begin(1) # 6p2 = refs.end(1) # 11
