Читаем Программирование на языке Ruby. Идеология языка, теория и практика применения полностью

m2 = reg.match(s2)

m.to_a[0]          # nil

m3 = reg.match(s3) # "New World"

В данном случае строка "New world" подходит, только если за ней не следует строка "Symphony".

<p>3.7. Обратные ссылки</p>

Каждая заключенная в круглые скобки часть регулярного выражения является отдельным соответствием. Они нумеруются, и есть несколько способов сослаться на такие части по номерам. Сначала рассмотрим традиционный «некрасивый» способ.

Сослаться на группы можно с помощью глобальных переменных $1, $2 и т.д:

str = "а123b45с678"

if /(a\d+)(b\d+)(c\d+)/ =~ str

 puts "Частичные соответствия: '#$1', '#$2', '#$3'"

 # Печатается: Частичные соответствия: 'а123', 'b45', 'c768'

end

Эти переменные нельзя использовать в подставляемой строке в методах sub и gsub:

str = "а123b45с678"

str.sub(/(a\d+)(b\d+)(c\d+)/, "1st=#$1, 2nd=#$2, 3rd=#$3")

# "1st=, 2nd=, 3rd="

Почему такая конструкция не работает? Потому что аргументы sub вычисляются перед вызовом sub. Вот эквивалентный код:

str = "а123b45с678"

s2 = "1st=#$1, 2nd=#$2, 3rd=#$3"

reg = /(a\d+)(b\d+)(c\d+)/

str.sub(reg,s2)

# "1st=, 2nd=, 3rd="

Отсюда совершенно понятно, что значения $1, $2, $3 никак не связаны с сопоставлением, которое делается внутри вызова sub.

В такой ситуации на помощь приходят специальные коды \1, \2 и т.д.:

str = "а123b45с678"

str.sub(/(a\d+)(b\d+)(c\d+)/, '1st=\1, 2nd=\2, 3rd=\3')

# "1st=a123, 2nd=b45, 3rd=c768"

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

str = "а123b45с678"

str.sub(/(a\d+)(b\d+)(c\d+)/, "1st=\1, 2nd=\2, 3rd=\3")

# "1st=\001, 2nd=\002, 3rd=\003"

Обойти эту неприятность можно за счет двойного экранирования:

str = "а123b45с678"

str.sub(/(a\d+)(b\d+)(c\d+)/, "1st=\\1, 2nd=\\2, 3rd=\\3")

# "1st=a123, 2nd=b45, 3rd=c678"

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

str = "а123b45с678"

str.sub(/(a\d+)(b\d+)(c\d+)/) { "1st=#$1, 2nd=#$2, 3rd=#$3" }

# "1st=a123, 2nd=b45, 3rd=c678"

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

Упомяну попутно о том, что существуют незапоминаемые группы (noncapturing groups). Иногда при составлении регулярного выражения нужно сгруппировать символы, но чему будет соответствовать в конечном счете такая группа, несущественно. На этот случай и предусмотрены незапоминаемые группы, описываемые синтаксической конструкцией (?:...):

str = "а123b45с678"

str.sub(/(a\d+)(?:b\d+)(c\d+)/, "1st=\\1, 2nd=\\2, 3rd=\\3")

# "1st=a123, 2nd=c678, 3rd="

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

Лично мне не нравится ни одна из двух нотаций (\1 и $1). Иногда они удобны, но никогда не бывают необходимы. Все можно сделать «красивее», в объектно-ориентированной манере.

Метод класса Regexp.last_match возвращает объект класса MatchData (как и метод экземпляра match). У этого объекта есть методы экземпляра, с помощью которых программист может получить обратные ссылки.

Обращаться к объекту MatchData можно с помощью квадратных скобок, как если бы это был массив соответствий. Специальный элемент с индексом 0 содержит текст всей сопоставляемой строки, а элемент с индексом n ссылается на n-ую запомненную группу:

pat = /(. + [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"}

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных