Впрочем, я немного уклонился от истины. Эти якоря на самом деле соответствуют началу и концу не строки символов (string),
а строки текста (line). Вот что произойдет, если те же самые образцы применить к строке, внутри которой есть символы новой строки:
string = "abc\ndef\nghi"
/def/ =~ string # 4
/abc/ =~ string # 0
/ghi/ =~ string # 8
/^def/ =~ string # 4
/def$/ =~ string # 4
/^abc/ =~ string # 0
/ghi$/ =~ string # 8
Однако имеются якоря
\A
и
\Z
, которые соответствуют именно началу и концу самой строки символов.
string = "abc\ndef\nghi"
/\Adef/ =~ string # nil
/def\Z/ =~ string # nil
/\Aabc/ =~ string # 0
/ghi\Z/ =~ string # 8
Якорь
\z
отличается от
\Z
тем, что последний устанавливает соответствие перед конечным символом новой строки, а первый должен соответствовать явно.
string = "abc\ndef\nghi"
str2 << "\n"
/ghi\Z/ =~ string # 8
/\Aabc/ =~ str2 # 8
/ghi\z/ =~ string # 8
/ghi\z/ =~ str2 # nil
Можно также устанавливать соответствие на границе слова с помощью якоря
\b
или с позицией, которая не находится на границе слова (
\B
). Примеры использования метода
gsub
показывают, как эти якоря работают:
str = "this is a test"
str.gsub(/\b/,"|") # "|this| |is| |a| |test|"
str.gsub(/\В/, "-") # "t-h-i-s i-s a t-e-s-t"
He существует способа отличить начало слова от конца.
3.5. Кванторы
Немалая часть аппарата регулярных выражений связана с обработкой необязательных элементов и повторений. Элемент, за которым следует вопросительный знак, необязателен; он может присутствовать или отсутствовать, а общее соответствие зависит от прочих частей регулярного выражения. (Этот квантор имеет смысл применять только к подвыражению ненулевой длины, но не к якорям.)
pattern = /ax?b/
pat2 = /а[xy]?b/
pattern =~ "ab" # 0
pattern =~ "acb" # nil
pattern =~ "axb" # 0
pat2 =~ "ayb" # 0
pat2 =~ "acb" # nil
Элементы
часто повторяются неопределенное число раз (для формулировки этого условия служит квантор
+
). Например, следующий образец соответствует любому положительному числу:
pattern = /[0-9]+/
pattern =~ "1" # 0
pattern =~ "2345678" # 0
Еще один типичный случай — образец, повторяющийся нуль или более раз. Конечно, это условие можно выразить с помощью кванторов
+
и
?
. Вот, например, как сказать, что после строки Huzzah должно быть нуль или более восклицательных знаков:
pattern = /Huzzah(!+)?/ # Скобки здесь обязательны.
pattern =~ "Huzzah" # 0
pattern =~ "Huzzah!!!!" # 0
Но есть и способ лучше. Требуемое поведение описывается квантором
*
.
pattern = /Huzzah!*/ # * применяется только к символу !
pattern =~ "Huzzah" # 0
pattern =~ "Huzzah!!!!" # 0
Как распознать американский номер социального страхования? С помощью такого образца:
ssn = "987-65-4320"
pattern = /\d\d\d-\d\d-\d\d\d\d/
pattern =~ ssn # 0
Но это не вполне понятно. Лучше явно сказать, сколько цифр должно быть в каждой группе. Это можно сделать, указав число повторений в фигурных скобках:
pattern = /\d{3}-\d{2}-\d{4}/
Необязательно, что такой образец будет короче, но он более понятен читателю программы.
Можно также использовать диапазоны, границы которых разделены запятой. Предположим, что номер телефона в Элбонии состоит из двух частей: в первой может быть от трех до пяти цифр, а во второй — от трех до семи. Вот как выглядит соответствующий образец:
elbonian_phone = /\d{3,5}-\d{3,7}/
Нижняя и верхняя границы диапазона необязательны (но хотя бы одна должна быть задана):