Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

# "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"}

Отметим, что объект

refs
— не настоящий массив. Поэтому, если мы хотим обращаться с ним как с таковым, применяя итератор
each
, следует сначала преобразовать его в массив с помощью метода
to_a
(как показано в примере).

Есть и другие способы нахождения сопоставленной подстроки внутри исходной строки. Методы

begin
и
end
возвращают смещения начала и конца соответствия. (Важно понимать, что смещение конца — это индекс символа, следующего за найденным соответствием.)

str = "alpha beta gamma delta epsilon"

# 0....5....0....5....0....5....

# (для удобства подсчета)

pat = /(b[^ ]+ )(g[^ ]+ )(d[^ ]+ )/

# Три слова, каждое из которых представляет собой отдельное соответствие.

refs = pat.match(str)

# "beta "

p1 = refs.begin(1) # 6

p2 = refs.end(1) # 11

# "gamma "

p3 = refs.begin(2) # 11

p4 = refs.end(2) # 17

# "delta "

p5 = refs.begin(3) # 17

p6 = refs.end(3) # 23

# "beta gamma delta"

p7 = refs.begin(0) # 6

p8 = refs.end(0) # 23

Аналогично метод

offset
возвращает массив из двух чисел: смещение начала и смещение конца соответствия. Продолжим предыдущий пример:

range0 = refs.offset(0) # [6,23]

range1 = refs.offset(1) # [6,11]

range2 = refs.offset(2) # [11,17]

range3 = refs.offset(3) # [17,23]

Части строки, которые находятся перед сопоставленной подстроки и после нее, можно получить методами

pre_match
и
post_match
соответственно. В том же коде:

before = refs.pre_match # "alpha "

after = refs.post_match # "epsilon"

3.8. Классы символов

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

/[aeiou]/ # Соответствует любой из букв а, е, i, о, и; эквивалентно

# /(a|e|i|o|u)/, только группа не запоминается.

Внутри класса символов управляющие последовательности типа

\n
по-прежнему распознаются, но такие метасимволы, как
.
и
?
, не имеют специального смысла:

/[.\n?]/ # Сопоставляется с точкой, символом новой строки,

# вопросительным знаком.

Поделиться:
Популярные книги

Газлайтер. Том 6

Володин Григорий Григорьевич
6. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 6

Москва. Путь к империи

Торопцев Александр Петрович
Научно-образовательная:
история
5.00
рейтинг книги
Москва. Путь к империи

Ведьмы из Броккенбурга. Барби 2

Соловьев Константин Анатольевич
3. Ведьмы из Броккенбурга
Фантастика:
фэнтези
5.00
рейтинг книги
Ведьмы из Броккенбурга. Барби 2

Печать пожирателя 6

Соломенный Илья
6. Пожиратель
Фантастика:
городское фэнтези
попаданцы
аниме
сказочная фантастика
фантастика: прочее
5.00
рейтинг книги
Печать пожирателя 6

Кодекс Практика. Тетралогия

Маревский Игорь
Внекатегорийный артефакт
Фантастика:
уся
фэнтези
фантастика: прочее
сянься
попаданцы
5.00
рейтинг книги
Кодекс Практика. Тетралогия

Олд мани

Голд Яна
Любовные романы:
современные любовные романы
остросюжетные любовные романы
фемслеш
5.00
рейтинг книги
Олд мани

Жанна д’Арк из рода Валуа. Книга 3

Алиева Марина Владимировна
Проза:
историческая проза
6.25
рейтинг книги
Жанна д’Арк из рода Валуа. Книга 3

«Витязь» в Индийском океане

Крепс Евгений Михайлович
Приключения:
морские приключения
путешествия и география
5.00
рейтинг книги
«Витязь» в Индийском океане

Барону наплевать на правила

Ренгач Евгений
7. Закон сильного
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Барону наплевать на правила

Личинка

Привалов Сергей
1. Звездный Бродяга
Фантастика:
боевая фантастика
космическая фантастика
рпг
попаданцы
5.00
рейтинг книги
Личинка

Франклин Рузвельт. Человек и политик (с иллюстрациями)

Бернс Джеймс Макгрегор
Проза:
историческая проза
6.25
рейтинг книги
Франклин Рузвельт. Человек и политик (с иллюстрациями)

Том 7. Художественная проза 1840-1855

Некрасов Николай Алексеевич
7. Собрание сочинений в пятнадцати томах
Проза:
русская классическая проза
5.00
рейтинг книги
Том 7. Художественная проза 1840-1855

Михаил Федорович

Сахаров Андрей Николаевич
3. Романовы. Династия в романах
Проза:
историческая проза
6.40
рейтинг книги
Михаил Федорович

Гаргантюа и Пантагрюэль

Рабле Франсуа
35. БВЛ. Серия первая
Старинная литература:
европейская старинная литература
5.00
рейтинг книги
Гаргантюа и Пантагрюэль