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

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

Жанры

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

/x*/ # То же, что /x{0,}

/x+/ # то же, что /x{1,}

Фразеология, применяемая при описании регулярных выражений, изобилует яркими терминами: жадный (greedy), неохотный (reluctant), ленивый (lazy) и собственнический (possessive). Самым важным является различие между жадными и нежадными выражениями.

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

"Where the"
, но на самом деле ему соответствует более длинная подстрока
"Where the sea meets the"
:

str = "Where the sea meets the moon-blanch'd land,"

match = /.*the/.match(str)

p match[0] # Вывести полученное соответствие:

# "Where the sea meets the"

Причина состоит в том, что оператор

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

str = "Where the sea meets the moon-blanch'd land,"

match = /.*?the/.match(str)

p match[0] # Вывести полученное соответствие:

# "Where the" .

Итак, оператор

*
жадный, если за ним не стоит
?
. То же самое относится к кванторам
+
и
{m,n}
и даже к самому квантору
?
.

Я не сумел найти разумных примеров применения конструкций

{m,n}?
и
??
. Если вам о них известно, пожалуйста, поделитесь со мной своим опытом.

Дополнительная информация о кванторах содержится в разделе 3.13.

3.6. Позитивное и негативное заглядывание вперед

Понятно, что регулярное выражение сопоставляется со строкой линейно (осуществляя при необходимости возвраты). Поэтому существует понятие «текущего положения» в строке, это аналог указателя файла или курсора.

Термин «заглядывание» означает попытку сопоставить часть строки, находящуюся дальше текущего положения. Это утверждение нулевой длины, поскольку даже если соответствие будет найдено, никакого продвижения по строке не произойдет (то есть текущее положение не изменится).

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

"New world"
будет сопоставлена, если за ней следует одна из строк
"Symphony"
или
"Dictionary"
. Однако третье слово не будет частью соответствия.

s1 = "New World Dictionary"

s2 = "New World Symphony"

s3 = "New World Order"

reg = /New World(?= Dictionary | Symphony)/

m1 = reg.match(s1)

m.to_a[0] # "New World"

m2 = reg.match(s2)

m.to_a[0] # "New World"

m3 = reg.match(s3) # nil

Вот пример негативного заглядывания:

reg2 = /New World(?! Symphony)/

m1 = reg.match(s1)

m.to_a[0] # "New World"

m2 = reg.match(s2)

m.to_a[0] # nil

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

В данном случае строка

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

3.7. Обратные ссылки

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

Сослаться на группы можно с помощью глобальных переменных

$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")

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

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

Мастер 6

Чащин Валерий
6. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 6

Кодекс Охотника XXVIII

Винокуров Юрий
28. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника XXVIII

Лекарь Империи 9

Карелин Сергей Витальевич
9. Лекарь Империи
Фантастика:
городское фэнтези
аниме
боевая фантастика
5.00
рейтинг книги
Лекарь Империи 9

Старый, но крепкий 4

Крынов Макс
4. Культивация без насилия
Фантастика:
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 4

Личинка

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

Черный Маг Императора 15

Герда Александр
15. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
фантастика: прочее
5.00
рейтинг книги
Черный Маг Императора 15

Андер Арес

Грехов Тимофей
1. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Андер Арес

Первый среди равных. Книга X

Бор Жорж
10. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Первый среди равных. Книга X

Дважды одаренный. Том II

Тарс Элиан
2. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Дважды одаренный. Том II

Государь

Мазин Александр Владимирович
7. Варяг
Фантастика:
альтернативная история
8.93
рейтинг книги
Государь

Бастард Императора. Том 3

Орлов Андрей Юрьевич
3. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 3

Законы Рода. Том 9

Мельник Андрей
9. Граф Берестьев
Фантастика:
городское фэнтези
попаданцы
аниме
дорама
фэнтези
фантастика: прочее
5.00
рейтинг книги
Законы Рода. Том 9

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й