Урок 3. Соответствие набору символов
28.03.2018
Категория: Регулярные выражения
В этом уроке вы научитесь работать с наборами символов. В отличие от точки ., которая соответствует любому отдельному символу (это вы узнали в предыдущем уроке), наборы дают возможность установить соответствие с определенными символами и символьными диапазонами.
Соответствие одному из нескольких символов
Как вы узнали из предыдущего урока, точке . соответствует один символ (как и любому литеральному символу). В заключительном примере урока 2, "Поиск отдельных символов", шаблон .a использовался для нахождения и na, и sa, причем точке . соответствовал и символ n, и символ s. Но что, если бы там был еще и файл ca1.xls с коммерческими данными по Канаде, а вам нужно найти только na и sa? Точке . соответствовал бы также и символ c, и потому имя этого файла также было бы найдено.
Чтобы найти только n или s, а не любой символ, нужно установить соответствие только с одним из этих двух символов. В регулярных выражениях набор символов определяется с помощью метасимволов [ и ]. Символы [ и ] определяют набор символов, состоящий из всех символов между ними. Любой член набора может соответствовать символу, с которым он совпадает. Вот пересмотренная версия заключительного примера предыдущего урока:
sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls ca1.xls
Регулярное выражение
[ns]a.\.xls
Результат
sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls ca1.xls
Используемое здесь регулярное выражение начинается с [ns]; это соответствует либо n, либо s (но не c или любому другому символу). Символы [ и ] не соответствуют никаким символам — они определяют набор. Литерал a соответствует a, точке . соответствует любой символ, наклонной черте с точкой \. соответствует ., а литералу xls соответствует xls. Если использовать этот шаблон, будут найдены только три нужных имени файла.
[ns]a.\.xls также не совсем правильный для данной задачи. Если бы существовал файл usa1.xls, этот шаблон нашел бы и его. При решении этой проблемы нужно учитывать еще и позиции символов, что будет сделано в уроке 6, "Соответствие позиций".
Наборы символов часто используются для выполнения операций поиска (или определения некоторых частей), не зависящих от регистра. Например:
Текст
The phrase "regular expression" is often abbreviated as RegEx or regex.
Регулярное выражение
[Rr]eg[Ee]x
Результат
The phrase "regular expression" is often abbreviated as RegEx or regex.
Используемый здесь шаблон содержит два набора символов: [Rr], которому соответствуют символы R и r, и [Ee], которому соответствуют символы E и e. Именно поэтому мы нашли как RegEx, так и regex. Однако цепочка REGEX не была бы найдена.
Использование диапазона набора символов
Обратимся к примеру со списком файлов. С последним использованным шаблоном, [ns]a.\.xls, связана еще одна проблема. Что было бы, если бы существовал файл sam.xls? Он тоже был бы найден, потому что точке . соответствуют все символы, а не только цифры.
Наборы символов могут решить эту проблему следующим образом:
Текст
sales1.xls orders3.xls sales2.xls sales1.xls apac1.xls europe2.xls sam.xls na1.xls na2.xls sa1.xls ca1.xls
Регулярное выражение
[ns]a[0123456789]\.xls
Результат
sales1.xls orders3.xls sales2.xls sales1.xls apac1.xls europe2.xls sam.xls na1.xls na2.xls sa1.xls ca1.xls
В этом примере шаблон был изменен так, чтобы первый символ был либо n, либо s, второй символ — только а, третьим символом могла быть любая цифра (указанная как [0123456789]). Обратите внимание, что файл sam.xls не был бы найден, потому что m не соответствует списку допустимых символов (10 цифр).
При работе с регулярными выражениями часто приходится определять диапазоны символов (от 0 до 9, от А до Z, и т.д.). Чтобы упростить работу с символьными диапазонами, в регулярных выражениях для определения диапазонов используется специальный метасимвол: - (дефис).
Вот тот же самый пример, но на сей раз используется диапазон:
Текст
sales1.xls orders3.xls sales2.xls sales1.xls apac1.xls europe2.xls sam.xls na1.xls na2.xls sa1.xls ca1.xls
Регулярное выражение
[ns]a[0-9]\.xls
Результат
sales1.xls orders3.xls sales2.xls sales1.xls apac1.xls europe2.xls sam.xls na1.xls na2.xls sa1.xls ca1.xls
Шаблон [0-9] функционально эквивалентен [0123456789], так что результат идентичен результату предыдущего примера.
Диапазоны могут состоять не только из цифр. Вот примеры правильных (допустимых) диапазонов:
-
A-Zсоответствует всем символам верхнего регистра отАдоZ. -
a-zсоответствует всем символам нижнего регистра отадоz. -
A-Fсоответствует только символам верхнего регистра отАдоF. -
A-zсоответствует всем символам, ASCII-коды которых находятся в диапазоне от ASCII-кодаАдо ASCII-кодаz. (Вероятно, вы никогда не должны использовать этот шаблон, потому что он включает также символы вроде[и^, которые в таблице ASCII расположены междуZиа).
Любые два символа ASCII могут быть определены как начало и конец диапазона. Однако обычно диапазоны составляются из некоторых (или всех) цифр и некоторых (или всех) алфавитных символов.
[3-1] не допустим). Такая ошибка часто делает неработоспособным весь шаблон.
-) рассматривается как специальный метасимвол только когда он используется между [ и ]. Вне набора - является литералом и будет соответствовать только -. Поэтому вне набора дефису - не обязан предшествовать никакой специальный знак.
Несколько диапазонов можно объединить в один набор. Например, следующий шаблон соответствует любому алфавитно-цифровому символу на верхнем или нижнем регистре, но не соответствует ничему, что не является ни цифрой, ни алфавитным символом:
[A-Za-z0-9]
Этот шаблон — сокращение для
[ABCDEFGHIJKLMNOPQRSTUVWXYZabcde fghijklmnopqrstuvwxyz0123456789]
Как видите, диапазоны намного сокращают запись регулярных выражений.
Ниже приведен еще один пример, на сей раз находятся RGB-значения (цвета, указанные в шестнадцатеричнои нотации, представляющей количество красного, зеленого и синего в создаваемом цвете). В Web-страницах RGB-значения определяются как #000000 (черный), #FFFFFF (белый), #FF0000 (красный), и т.д. RGB-значения могут быть определены на верхнем или нижнем регистре, так что значение #FF00ff (сиреневый) также является допустимым. Вот пример:
Текст
<BODY BGCOLOR="#336633" TEXT="#FFFFFF"
MARGINWIDTH="0" MARGINHEIGHT="0"
TOPMARGIN="0" LEFTMARGIN="0">
Регулярное выражение
#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]
Результат
<BODY BGCOLOR="#336633" TEXT="#FFFFFF" MARGINWIDTH="0" MARGINHEIGHT="0" TOPMARGIN="0" LEFTMARGIN="0">
Используемый здесь шаблон содержит символ # как буквальный текст, а затем набор символов [0-9A-Fa-f], повторенный шесть раз. Это соответствует символу #, за которым следует шесть символов, каждый из которых должен быть цифрой или буквой от А до F (на верхнем или нижнем регистре).
Соответствие с чем угодно, кроме...
Наборы символов обычно используются для того, чтобы определить список символов, любой из которых может соответствовать одному символу. Но иногда проще указать список символов, ни с одним из которых не должен совпадать данный символ. Другими словами, нужно указать соответствие с чем угодно, кроме того, что указано в списке шаблона.
Вместо того чтобы перечислять каждый символ, можно, используя метасимвол ^, инвертировать наборы символов. Вот пример:
Текст
sales1.xls orders3.xls sales2.xls sales1.xls apac1.xls europe2.xls sam.xls na1.xls na2.xls sa1.xls ca1.xls
Регулярное выражение
[ns]a[^0-9]\.xls
Результат
sales1.xls
orders3.xls
sales2.xls
sales1.xls
apac1.xls
europe2.xls
sam.xls
na1.xls
na2.xls
sa1.xls
ca1.xls
Используемый в этом примере шаблон — полная противоположность ранее использованного шаблона. Диапазон [0-9] соответствует всем цифрам (и только цифрам). Выражение [^0-9] соответствует чему угодно, кроме цифр указанного диапазона. Также [ns]а[^0-9]\.xls соответствует sam.xls, но не na1.xls, na2.xls или sa1.xls.
^ отрицает все символы или диапазоны в наборе, а не только символ или диапазон, которому он предшествует.
Резюме
Метасимволы [ и ] используются для того, чтобы определить наборы символов, любой из которых может соответствовать данному (операция ИЛИ в отличие от И). Наборы символов могут быть перечислены явно или определены как диапазоны с помощью метасимвола -. Используя ^, наборы символов можно инвертировать, инвертированному шаблону соответствует что угодно, кроме указанных в нем символов.