ip1 = '9.53.97.102'

if ip1 =~ ip_pat # Печатается: 'да'

 puts 'да'

else

 puts 'нет'

end

Надо признать, что в определении переменной num слишком много символов обратной косой черты. Определим ее в виде регулярного выражения, а не строки:

num = /(d1[01]?dd|2[0-4]d|25[0-5])/

Когда одно регулярное выражение интерполируется в другое, вызывается метод to_s, который сохраняет всю информацию из исходного регулярного выражения.

num.to_s # '(?-mix:(\d|[01]?\d\d|2[0-4]\d|25[0-5]))'

Иногда для встраивания удобно использовать регулярное выражение, а не строку. Хорошее эвристическое правило: интерполируйте регулярные выражения, если веских причин интерполировать строки.

IPv6-адреса пока не очень широко распространены, но для полноты рассмотрим и их. Они записываются в виде восьми шестнадцатеричных чисел, разделенных двоеточиями, с подавлением начальных нулей.

num = /[0-9A-Fa-f]{0,4}/

pat = /^(#{num}:){7}#{num}$/

ipv6_pat = Regexp.new(pat)

v6ip = 'abcd::1324:ea54::dead::beef'

if v6ip =~ ipv6_pat # Печатается: 'да'

 puts 'да'

else

 puts 'нет'

end

3.14.2. Сопоставление с парой «ключ-значение»

Иногда приходится работать со строками вида «ключ=значение» (например, при разборе конфигурационного файла приложения).

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

pat = /(w+)s*=s*(.*?)$/

str = 'color = blue'

matches = pat.match(str)

puts matches[1] # 'color'

puts matches[2] # 'blue'

3.14.3. Сопоставление с числами, записанными римскими цифрами

Следующее довольно сложное регулярное выражение сопоставляется с любым правильно записанным римскими цифрами числом (до 3999 включительно). Как и раньше, для удобства восприятия образец разбит на части:

rom1 = /m{0,3}/i

rom2 = /(d?c{0,3}|с[dm])/i

rom3 = /(l?x{0,3}|x[lс])/i

rom4 = /(v?i{0,3}|i[vx])/i

roman = /^#{rom1}#{rom2}#{rom3}#{rom4}$/

year1985 = 'MCMLXXXV'

if year1985 =~ roman # Печатается: 'да'

 puts 'да'

else

 puts 'нет'

end

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

# Это не работает!

rom1 = /m{0,3}/

rom2 = /(d?c{0,3}|с[dm])/

rom3 = /(l?x{0,3}|x[lс])/

rom4 = /(v?i{0,3}|i[vx])/

roman = /^#{rom1}#{rom2}#{rom3}#{rom4}$/i

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

rom1.to_s # '(?-mix:m{0,3})'

Обратите внимание, что метод to_s запоминает флаги для каждого выражения; тем самым флаг всего выражения перекрывается.

3.14.4 Сопоставление с числовыми константами

Сопоставление с простым целым десятичным числом — самое простое. Число состоит из необязательного знака и последовательности цифр (правда, Ruby позволяет использовать знак подчеркивания в качестве разделителя цифр). Отметим, что первая цифра не должна быть нулем, иначе число будет интерпретироваться как восьмеричное.

int_pat = /^[+-]?[1-9][d_]*$/

Целые константы в других системах счисления обрабатываются аналогично. Образцы для шестнадцатеричных и двоичных чисел сделаны не чувствительными к регистру, так как они содержат букву:

hex_pat = /^[+-]?0x[da-f_]+$/i

oct_pat = /^[+-]?0[0-7_]+$/

bin_pat = /^[+-]?0b[01_]+$/i

Сопоставить число с плавающей точкой в обычной нотации несколько сложнее. Последовательности цифр по обе стороны десятичной точки необязательны, но хотя бы одна цифра должна быть:

float_pat = /^(d[d_]*)*.[d_]*$/

Образец для чисел, записанных в научной нотации, основан на предыдущем:

sci_pat = /^(d[d_]*)?.[d_]*(e[+-]?)?(_*d[d_]*)$/i

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату