Урок 7. Использование подвыраженийМетасимволы и соответствие символов составляют основу мощи регулярных выражений, как было продемонстрировано в предыдущих уроках. В этом уроке вы научитесь группировать выражения и использовать подвыражения. Понятие подвыражения
Соответствие нескольким вхождениям символа было введено в уроке 5, "Повторение совпадений", где указывалось, что
В обоих этих примерах (а на самом деле во всех примерах к настоящему времени) метасимволы повторения ( Например, разработчики HTML-документов часто размещают неразрывные пробелы между словами, чтобы гарантировать, что текст не будет разорван на строки между такими словами. Предположим, что в HTML-документе нужно найти местонахождение всех повторений неразрывных пробелов (чтобы заменить их кое-чем другим). Boт пример: Текст Hello, my name is Ben Forta, and I am the author of books on SQL, ColdFusion, WAP, Windows 2000, and other subjects. Регулярное выражение {2,} Результат Hello, my name is Ben Forta, and I am the author of books on SQL, ColdFusion, WAP, Windows 2000, and other subjects.
Группировка подвыраженийТеперь мы приступаем к изучению подвыражений. Подвыражения — части большего выражения; части группируются так, чтобы они обрабатывались как единый объект. Подвыражения заключаются между символами ( и ). ЗамечаниеСкобки ( и ) — метасимволы. Чтобы найти символы ( и ), их нужно защитить, т.е. задать как \( и \). Чтобы продемонстрировать использование подвыражений, давайте повторно рассмотрим предыдущий пример: Текст Hello, my name is Ben Forta, and I am the author of books on SQL, ColdFusion, WAP, Windows 2000, and other subjects. Регулярное выражение ( ){2,} Результат
Hello, my name is Ben Forta, and I am the author of
books on SQL, ColdFusion, WAP, Windows 2000, and
other subjects.
Подвыражение
Вот еще один пример. На сей раз регулярное выражение используется, чтобы определить местонахождение IP-адресов. IP-адрес — это четыре числа, разделенных точками. Вот пример IP-адреса: Текст Pinging hog.forta.com [12.159.46.200] with 32 bytes of data: Регулярное выражение \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} Результат
Pinging hog.forta.com [12.159.46.200] with 32 bytes of data:
Каждому шаблону
Шаблон Текст Pinging hog.forta.com [12.159.46.200] with 32 bytes of data: Регулярное выражение (\d{1,3}\.){3}\d{1,3} Результат
Pinging hog.forta.com [12.159.46.200] with 32 bytes of data:
Этот шаблон работал точно так же, как и предыдущий, но его синтаксис немного отличается. Выражение Замечание
Шаблон Замечание
Некоторые пользователи любят заключать части выражений в скобки, точно так же, как и подвыражения, потому что это повышает удобочитаемость; предыдущий шаблон мог бы быть записан как Использование подвыражений для группировки крайне важно. Рассмотрим еще один пример, в котором повторений нет вообще. В этом примере мы попытаемся найти год в записи о пользователе: Текст ID: 042 SEX: M DOB: 1967-08-17 Status: Active Регулярное выражение 19|20\d{2} Результат
ID: 042
SEX: M
DOB: 1967-08-17
Status: Active
В этом примере шаблон должен был определить местонахождение года (четырехразрядное число), но для большей
точности первые две цифры были указаны явно как 9 и 20. Как объяснено в уроке 3, "Соответствие набору символов",
Решение состоит в том, чтобы сгруппировать Текст ID: 042 SEX: M DOB: 1967-08-17 Status: Active Регулярное выражение (19|20)\d{2} Результат
ID: 042
SEX: M
DOB: 1967-08-17
Status: Active
Если оператор | поместить в подвыражение, то он будет знать, что требуется найти один из вариантов в группе. Таким образом, шаблон ЗамечаниеВ этом уроке описано использование подвыражений для группировки, однако есть еще одно чрезвычайно важное применение подвыражений. Оно описано в уроке 8, "Использование ссылок назад". Вложение подвыраженийПодвыражения могут быть вложены. Одни подвыражения могут быть вложены в другие подвыражения, в свою очередь вложенные в третьи подвыражения, и т.д. Возможность вкладывать подвыражения позволяет создавать невероятно мощные выражения. С другой стороны, такой шаблон может оказаться довольно замысловатым, трудночитаемым, несколько отпугивающим своей сложностью, в таком случае его придется декодировать. Правда, чем сложнее вложенное подвыражение, тем реже оно встречается. Чтобы продемонстрировать использование вложенных подвыражений, мы снова рассмотрим пример с IP-адресами. Вот использованный ранее шаблон (подвыражение повторено три раза, а за ним в заключение следует число): (\d{1,3}\.){3}\d{1,3} Так что же неправильно в этом шаблоне? Синтаксически все правильно. IP-адрес действительно составлен из четырех чисел; каждое из них содержит от одной до трех цифр, причем числа отделены друг от друга точками. Данный шаблон будет соответствовать любому правильному (допустимому) IP-адресу. Но он будет соответствовать не только правильным IP-адресам — недопустимые IP-адреса также будут соответствовать ему. IP-адрес составлен из 4 байт, и потому IP-адрес, например 12.159.46.200, является представлением 4 байт. Поэтому значения этих четырех чисел из IP-адреса могут быть записаны в одном байте, а потому они находятся в диапазоне от 0 до 255. Это означает, что ни одно из чисел в IP-адресе не может быть больше, чем 255. А наш шаблон допускает также и другие числа (например, 345, 700 и 999), которые недопустимы в IP-адресах. ЗамечаниеИз этого важно извлечь урок. Записать регулярное выражение, которое соответствует тому, что вы хотите и ожидаете, не составит большого труда. Намного сложнее записать регулярное выражение, которое учитывает все возможные сценарии так, чтобы это выражение не соответствовало тому, с чем вы не хотите установить соответствие. Было бы хорошо, если бы можно было определить диапазон допустимых значений, но регулярные выражения со¬ответствуют символам и на самом деле не имеют никакого представления, что значат эти символы. Так что математические вычисления — не их стихия. Можно ли записать нужное регулярное выражение? В некоторых случаях можно. Чтобы создать нужное регулярное выражение, необходимо точно определить все те цепочки, которым оно должно соответствовать, и все те цепочки, которым оно не должно соответствовать. Ниже приведены правила, определяющие правильные (допустимые) комбинации в каждом числе IP-адреса:
Если последовательно придерживаться этих правил, становится ясно, что действительно есть шаблон, который может найти все IP-адреса и только их. Вот пример: Текст Pinging hog.forta.com [12.159.46.200] with 32 bytes of data: Регулярное выражение (((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3} ((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5])) Результат
Pinging hog.forta.com [12.159.46.200] with 32 bytes of data:
Рассмотрим, как работает этот шаблон. Прежде всего отметим, что он работает потому, что в нем используется ряд вложенных подвыражений. Проанализируем, например, следующее выражение, содержащее 4 подвыражения: (((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.) Подвыражение (\d{1,2}) находит любое число в диапазоне от 0 до 99. Подвыражение (1\d{2}) соответствует любому трехзначному числу, начинающемуся с 1 (после 1 следуют любые две цифры), т.е. любому числу в диапазоне от 100 до 199. Подвыражение (2[0-4]\d) находит числа от 200 до 249, а (25[0-5]) находит числа от 250 до 255. Каждое из этих подвыражений является операндом другого подвыражения, составленного из этих подвыражений-операндов с помощью знака операции |. Поэтому будет выполняться поиск числа, соответствующего одному из этих подвыражений, а не всем. После диапазона чисел следует шаблон \., поэтому будет выполняться поиск точки. Так что полученное подвыражение соответствует всей последовательности цифр и точке (всему числу и точке после него). Это подвыражение заключено в скобки, т.е. само рассматривается как часть подвыражения, которое повторяется три раза с помощью {3}. В конце диапазон чисел повторяется снова, но на этот раз после него нет шаблона \.; этот диапазон как раз и соответствует последнему числу в IP-адресе. Именно благодаря тому, что каждое из четырех чисел находится в диапазоне от 0 до 255, этот шаблон действительно находит все правильные IP-адреса и отвергает все ошибочные. ЗамечаниеРегулярные выражения, подобные этому, могут выглядеть весьма запутанно. Ключ к пониманию их состоит в том, чтобы найти их подвыражения, а затем проанализировать и понять каждое из подвыражений по отдельности. Начать надо с самых внутренних частей и продвигаться наружу, т.е. к более сложным выражениям, состоящим из уже разобранных подвыражений. Ни в коем случае не нужно пробовать читать символ за символом с самого начала. Каким бы сложным ни было регулярное выражение, при рекомендуемом подходе оно окажется намного проще, чем показалось вам на первый взгляд. РезюмеПодвыражения используются для группирования частей выражения; они заключаются в круглые скобки ( и ). Обычно подвыражения используются для того, чтобы точно указать, к каким частям выражения относятся метасимволы повторения, и правильно определить операнды оператора ИЛИ. При необходимости подвыражения могут быть вложены. |
||