Синтаксис регулярных выражений
Вступление
Регулярные выражения представляют собой строку, которая начинается с символа разделителя, за которым следует непосредственно регулярное выражение, затем еще один символ разделителя и потом необязятельный список модификаторов.
Метасимволы
\ | общий экранирующий символ, допускающий несколько вариантов применения |
^ | декларирует начало данных (или строки в многострочном режиме) |
$ | декларирует конец данных или до завершения строки (или окончание строки в многострочном режиме) |
. | соответствует любому символу, кроме перевода строки (по умолчанию) |
[ | начало описания символьного класса |
] | конец описания символьного класса |
| | начало ветки альтерннативного выбора |
( | начало подмаски |
) | конец подмаски |
? | расширяет смысл метасимвола (, является также квантификатором, означающим 0 или 1 вхождение, также преобразует жадные квантификаторы в ленивые) |
* | квантификатор, означающий 0 или более вхождений |
+ | квантификатор, означающий 1 или более вхождений |
< | начало количественного квантификатора |
> | конец количественного квантификатора |
Символьные классы
Открывающая квадратная скобка объявляет начало символьного класса, завершаемого закрывающей квадратной скобкой. Символ ] не имеет специального значения, и в случае, если закрывающая квадратная скобка необходима как член символьного класса, она должна быть первым символом непосредственно после открывающей квадратной скобки (если используется метасимвол ^ , то непосредственно после него), либо экранироваться при помощи обратного слеша.
Символьный класс соответствует одиночному символу обрабатываемой строки, причем сам символ должен содержаться в наборе, определяемым классом. В случае, если первым символом описания класса является ^ логика работы инвертируется: класс соответствует одиночному символу, который не содержится в наборе, определяемым классом. Если символ ^ необходим как член класса, его не следует помещать первым символом в описании класса либо необходимо экранировать при помощи обратного слеша.
. | Точка — любой символ |
[ ] | квадратные скобки — класс символов («любое из») |
[^ ] | негативный класс символов («любое кроме») |
— | тире — обозначение последовательности в классе символов («[0-9]» — цифры) |
alnum | буквы и цифры |
alpha | буквы |
ascii | символы с кодами 0 — 127 |
blank | только пробел или символ табуляции |
cntrl | управляющие символы |
digit | десятичные цифры (то же самое, что и \d) |
graph | печатные символы, исключая пробел |
lower | строчные буквы |
печатные символы, включая пробел | |
punct | печатные символы, исключая буквы и цифры |
space | пробельные символы(почти то же самое, что и \s) |
upper | прописные буквы |
word | символы «слова» (то же самое, что и \w) |
xdigit | шестнадцатеричные цифры |
Класс пробельных символов space — это горизонтальная табуляция, перевод строки, вертикальная табуляция, разрыв страницы, возврат каретки и пробел. Учтите, что этот список включает вертикальную табуляцию. Это отличает space от \s , который не включает этот символ, для совместимости с Perl.
Название word — это расширение Perl, а blank — расширение GNU, начиная с версии Perl 5.8. Другое расширение Perl — это отрицание, которое указывается символом ^ после двоеточия. Например, [12[:^digit:]] совпадет с «1», «2», или с любой не-цифрой.
Квантификатор
* | Соответствие возникнет, если предыдущий символ будет повторяться любое число раз (в том числе и 0 раз). |
+ | Соответствие возникнет, если предыдущий символ будет повторяться хотя бы один раз. То есть отличие от квантификатора * , здесь требуется, чтобы предшествующий символ был бы хотя бы один раз. |
? | Соответствие возникнет, если предыдущего символа вообще не было, либо он был только один раз. |
Соответствие возникнет, если предыдущий символ будет повторяться ровно n раз. | |
Соответствие возникнет, если предыдущий символ будет повторяться n или более раз. | |
Соответствие возникнет, если предыдущий символ будет повторяться от n до m раз. |
Якоря
^ | привязка к началу строки |
$ | привязка к концу строки |
По умолчанию, вне символьного класса метасимвол начала строки ^ соответствует началу обрабатываемых данных (если не используются модификаторы). Внутри символьного класса он ^ имеет совершенно другое значение.
Метасимвол начала строки ^ не обязан быть первым символом шаблона в случае, если в шаблоне используются несколько альтернатив, но должен быть первым символом в каждой из альтернатив, в которой он встречается, если шаблон когда-либо сопоставим с соответствующей веткой. Если все альтернативы начинаются с метасимвола начала строки ^ , то шаблон ограничен для совпадения исключительно в начале строки, говорят что шаблон «заякорен». (Существуют и другие способы «заякорить» шаблон).
Соответствие метасимволу конца строки $ достигается только в конце строки или непосредственно перед последним символом в случае, если им является перевод строки (если модификаторы не указаны). Метасимвол конца строки $ не обязан быть последним символом шаблона в случае, если используется несколько альтернатив, но должен быть последним символом в каждой альтернативе, в которой он фигурирует. Внутри символьного класса символ $ не имеет специального значения.
Альтернативный выбор
Символ вертикальной черты | используется для разделения альтернативных масок. Например, шаблон яблоко|груша соответствует как «яблоко», так и «груша». Допустимо указывать любое количество альтернатив, также допустимо указывать пустые альтернативы (соответствуют пустой строке). В процессе поиска соответствия просматриваются все перечисленные альтернативы слева направо, останавливаясь после первого найденного соответствия. В случае, если альтернативные варианты перечислены в подмаске, то весь шаблон совпадет только в случае соответствия одного из альтернативных вариантов подмаски и остатка основного шаблона.
Условные подмаски
В PCRE реализована возможность подчинять шаблон условию либо выбирать из двух условных подмасок в зависимости от успеха сопоставления предыдущей подмаски. Условные подмаски имеют две допустимые формы использования:
(?(condition)yes-pattern) | В случае выполения условия condition, используется подмаска yes-pattern |
(?(condition)yes-pattern|no-pattern) | В случае выполения условия condition, используется подмаска yes-pattern, в противном случае no-pattern |
Условия бывают двух видов. В случае, если между скобками заключены цифры, условие будет выполняться в том случае, если подмаска с соответствующим номером была успешно сопоставлена. Рассмотрим следующий шаблон (он содержит незначащий пробел для удобства чтения, подразумевается использование модификатора PCRE_EXTENDED), разделив его для удобства на три смысловые части:
Первая часть соответствует опциональной открывающей скобке, и в случае если она присутствует, захватывает ее как значение первой подмаски.
Следующая часть соответствует одному или более символам, отличным от круглой скобки.
Третья часть является условной подмаской, зависящей от результата сопоставления первой подмаски. В случае, если в начале обрабатываемых данных была обнаружена открывающая круглая скобка, условие будет интерпретировано как истина, и, следовательно, для успешного сопоставления третьей части шаблона необходима закрывающая круглая скобка. В противном случае, поскольку не указана вторая ветвь условного шаблона, третья часть будет сопоставлена с пустой строкой. Суммируя все вышесказанное, приведенный шаблон совпадает с последовательностью не-скобок, возможно, заключенной в круглые скобки.
Если условием является строка (R), оно будет выполнено, если будет произведен рекурсивный вызов к шаблону или подмаске. На «самом верхнем уровне» условие ложно.
Если условие не является последовательностью цифр или (R), оно должно быть утверждением. Это может быть либо положительная или отрицательная проверка последующего либо предыдущего текста. Рассмотрим данный шаблон, снова содержащий незначащие пробелы, с двумя альтернативами на второй строке:
Приведен пример с утверждающим условием касательно предшествующего текста, которое выполняется для необязательной последовательности не-букв с последующей буквой. Говоря другими словами, указанное условие проверяет наличие хотя бы одной предшествующей буквы. В случае, если буква найдена, выполняется сопоставление с первой альтернативой, в противном случае — со второй альтернативой. Приведенный шаблон соответствует строкам двух видов: dd-aaa-dd либо dd-dd-dd, где aaaa — это буквы, а dd — цифры.
Комментарии
Служебная последовательность (?# обозначает начало комментария, который продолжается до ближайшей закрывающей скобки. Вложенные скобки не допускаются. Символы, находящиеся внутри комментария, не принимают участия в сопоставлении шаблона.
Краткое описание регулярных выражений: POSIX и PCRE
Часть 1: Регулярные выражения
Начну с того, что php поддерживает два стандарта регулярных выражений: POSIX и, начиная с четвертой версии, совместимые с Perl. Первый стандарт используется и сервером Apache в mod_rewrite а так же. MySQL в своих запросах (поищите слово «REGEXP» в руководстве по mysql, может сразу поймете, а я об этом позже расскажу). Второй, как ясно из названия, используется в системе perl. Два этих стандарта различаются несильно — во втором есть специальные символы, заменяющие наиболее часто используемые классы символов (например, цифры — d, а буквы и цифры — w) и специальные параметры шаблонов, позволяющие определять регистрозависимость поиска, привязку к концам строк и т.д (в функциях стандарта POSIX регистрозависимость реализована просто: есть функции ereg и ereg_eeplace, есть eregi (insensitive) и eregi_replace). В остальном же оба стандарта совместимы, а приемы написания шаблонов одинаковые.
Если вы работали с Norton/Volkov/Windows Commander или Far, то знаете такую вещь как wildcards. Например: delete c:windows*.* удаляет все файлы из указанной директории. В именах файлов особых изощрений делать не приходится, поэтому система простая: символ * означает любой набор символов, в том числе пустой (*.txt), символ ? — любой символ или никакого символа (document?.txt) и еще какие-то обозначения для букв и цифр (я, честно говоря, ими давно не пользовался, поэтому так не вспомню).
В регулярных выражениях подход иной. Система в первую очередь универсальна и должна уметь находить соответствия строк любым самым сложным запросам (странно, что я говорю «должна уметь», система ведь уже «умеет». Надеюсь читатель простит мне такие фразы, ведь они все относятся к уже работающей системе регулярных выражений.) Сейчас я назову термины, которые буду употреблять в дальнейшем, чтобы избежать растяжимых (в прямом и переносном смысле) определений.
Итак, задача системы — помимо четко заданных символов («Вася(.*)Пупкин») позволить указать пользователю поиск заданного количества заданных символов. В приведенном примере с Васей Пупкиным между словами задано любое количество любых символов. Если надо найти шесть цифр, то пишем «[0-9]<6>» (если, например, от шести до восьми цифр, тогда «[0-9]<6,8>«). К чему это все? К тому, что в отличие от wildcard из операционной системы, здесь разделены такие вещи как указатель набора символов и указатель необходимого количества: Вместо набора символов может быть использовано обозначение любого символа — точка, может быть указан конкретный набор символов (поддерживаются последовательности — упоминавшиеся «0-9»). Может быть указано «кроме данного набора символов».
Указатель количества символов в официальной документации по php называется «квантификатор». Термин удобный и не несет в себе кривотолков. Итак, квантификатор может иметь как конкретное значение — либо одно фиксированное («<6>«), либо как числовой промежуток («<6,8>«), так и абстрактное «любое число, в т.ч. 0» («*»), «любое натуральное число» — от 1 до бесконечности («+»: «document[0-9]+.txt»), «либо 0, либо 1» («?»). По умолчанию квантификатор для данного набора символов равен единице («document[0-9].txt»).
Разумеется, для более гибкого поиска сочетаний эти связки «набор символов — квантификатор» можно объединять в метаструктуры.
Как всякий гибкий инструмент, регулярные выражения гибки, но не абсолютно: зона их применения ограничена. Например, если вам надо заменить в тексте одну фиксированную строку на другую, фиксированную опять же, пользуйтесь str_replace. Разработчики php слезно умоляют не пользоваться ради этого сложными функциями ereg_replace или preg_replace, ведь при их вызове происходит процесс интерпретации строки, а это серьезно потребляет ресурсы системы. К сожалению, это любимые грабли начинающих php-программистов (даже я сам, волею судьбы, сперва увидел в руководстве функцию ereg_replace, а только потом, позже, str_replace).
Пользуйтесь функциями регулярных выражений только если вы не знаете точно, какая «там» строка. Из примеров: поисковый код этого сайта, в котором из строки поиска вырезаются служебные символы и короткие слова а так же вырезаются лишние пробелы (вернее, все пробелы сжимаются: » +» заменяется на один пробел). При помощи этих функций я проверяю email пользователя, оставляющего свой отзыв. Много полезного можно сделать, но важно иметь в виду: регулярные выражения не всесильны. Например, сложную замену в большом тексте ими лучше не делать. Ведь, к примеру, комбинация «(.*)» в программном плане означает перебор всех символов текста. А если шаблон не привязан к началу или концу строки, то и сам шаблон «двигается» программой через весь текст, и получается двойной перебор, вернее перебор в квадрате. Нетрудно догадаться, что еще одна комбинация «(.*)» означает перебор в кубе, и так далее. Возведите в третью степень, скажем, 5 килобайт текста. Получается 125 000 000 000 (прописью: сто двадцать пять миллиардов операций). Конечно же, если подходить строго, там стольких операций не будет, а будет раза в четыре-восемь меньше, но важен сам порядок цифр.
Итак, принципы, достоинства и недостатки описаны, теперь надо переходить к конкретике. Два (возможно, сразу следующих) выпуска будут посвящены двум стандартам регулярных выражений — POSIX и PCRE. Описание базовых принципов и понятий работы регулярных выражений.
Часть 2: POSIX
Продолжаем наш разговор. Предыдущий выпуск был вводным, теорией. Сегодня как бы основная часть рассказа — стандарт POSIX. В следующем выпуске я опишу различия, вернее сказать надстройки стандарта совместимого с perl. Итак, обо всем по порядку.
Набор символов
Особо объяснять ничего не нужно. Разве что следующее: не пользуйтесь классом символов для обозначения всего лишь одного (вместо «[ ]+» вполне сойдет » +»). Не пишите в классе символов точку — это ведь любой символ, тогда другие символы в классе будут просто лишними (а в негативном классе получится отрицание всех символов).
Квантификатор
Если нужно указать только необходимый минимум, а максимума нет, просто ставим запятую и не пишем второе число: «<5,>» («минимум 5»). Для наиболее часто употребляемых квантификаторов есть специальные обозначения:
На практике такие символы используются чаще , чем фигурные скобки .
Якоря
^ привязка к началу строки
$ привязка к концу строки
Эти символы должны стоять соответственно в самом начале и в самом конце строки. Чтобы интерпретатор корректно понял символ $ в конце, желательно добавить к нему обратный слэш: ereg(«foo$», $bar)
Структура
Сейчас будет сложное описание, мне оно и самому не нравится. Эта вещь необходима для сложных запросов. Например, вам надо, чтобы в тексте были либо только маленькие буквы, либо только большие, либо только цифры. Класс символов «[a-zA-Z0-9]» не подходит. Тогда пишем такое:
Вертикальная черта — знак «или» регулярных выражений (знака «и», естественно, не существует — это и есть само регулярное выражение). Разделенные вертикальной чертой шаблоны в официальной документации называются альтернативными ветвями (это подразумевает ветвление, т.е. наличие вложенных альтернативных ветвей). Программа сравнивает со строкой все ветви (проходясь по их ряду слева направо), до первого совпадения (это важно учесть, если у вас сложное выражение со вложенными ветвями). Для разделения уровней и отделения этого дерева альтернатив от остального шаблона используются обычные скобки. Если те же большие/маленькие буквы/цифры надо искать внутри контейнера тегов:
Из сложного это, кажется, все. Теперь о более простом. Скобки по-научному называются subpattern (вложенный шаблон). И используются не только для сложных вариантов шаблонов, но и для гибкой замены фрагментов текста или получения их в переменную. К примеру, для печатной версии текста дублируем адреса ссылок текстом в скобках:
Первые скобки — первый вложенный шаблон — можно получить «на выходе» через обозначение «n» (поскольку обратный слэш в php и многих других языках используется для спецсимволов, надо поставить перед ним еще один такой же, чтобы прогамма понимала его буквально). Под нулевым номером — вся совпавшая строка. У себя в печатной версии статьи я не пишу ссылки сразу в тексте, а делаю их список в конце примерно так:
Ссылки, использованные в выпуске:
Функция ereg (и eregi), если ей указать в третьем параметре переменную, то туда будут записаны все подстроки в виде двухмерного массива.
Это, собственно, все. Дальше нужно только уметь составлять шаблоны. Приведу несколько примеров.
* Переписывание адресов сервером Apache (как я уже отметил, Apache работает со стандартом POSIX).
* Поиск по базе данных: из пользовательского поискового запроса делается sql-запрос. Если отбросить создание статистики поиска (сколько найдено всего, сколько по каждому слову), то получится, что необходимо всего 6-7 строк кода. Там же описана и подсветка слов в результатах поиска. Кстати, важное замечание: перед тем, как вырезать короткие слова из строки я заменяю пробелы между словами на двойные. Почему? Потому что совпадающие с шаблоном строки не должны наезжать друг на друга.
Объясню подробнее. Если в шаблоне нет никаких якорей, система проходится по тексту слева направо, и если найдено совпадение, кидает его в какие-то переменные, а затем перескакивает на следующий символ после совпавшего фрагмента. Мы ищем по шаблону «пробел, два непробела, пробел», а пробелы одиночные. Программа находит «пробел-короткое слово-пробел», заменяет это на один пробел, а затем перескакивает на. первую букву следующего слова. Это не пробел, поэтому даже если следующее слово тоже короткое, оно под шаблон не подойдет. Поэтому-то и надо предварительно заменить пробелы на двойные.
* Как хранить новости в файлах и не бегать циклом по дате:
4. Проверка правильного написания email-а:
На этом все. В следующем выпуске — стандарт PCRE, точнее дополнительные возможности, которые он предоставляет.
Часть 3: PCRE
И вот, наконец, серия выпусков про регулярные выражения подходит к концу. Поговорим о регулярных выражениях совместимых с Perl (Perl compatible regular expressions — PCRE).
Самое главное их преимущество перед POSIX, как мне уже подсказывают — возможность «жадного» поиска. Вопросительный знак в PCRE выступает еще и как минимизатор квантификатора: .*?Найдет минимальную подходящую строку. Вроде бы ничего особенного? Нет, это очень особенная вещь. Например, какой пример я приводил в прошлом выпуске про печатную версию текста?
То есть, внури ссылки не должно быть тегов (например «. «). Если же сделать так:
Тогда мы получим. Правильно, весь текст между началом первой и концом последней ссылки. Все проблемы снимает жадный поиск.
Программа подберет для всех ссылок минимальную подходящую строку, т.е. только до тега «». Описывать значение такой особенности PCRE нет смыла — оно огромное. Идем дальше.
Цифры теперь можно обозначить не как «[0-9]», а просто «d». Не-цифры
(«[^0-9]») как «D». Очень удобно. Вот остальные обозначения:
Рекомендую заглянуть в выпуски про поиск — там эти символы используются.
Строка шаблона, как вы уже заметили, начинается и заканчивается слэшами. Для чего нужен первый слэш, не знаю. Последний нужен для отделения шаблона от параметров. Параметры, которые я понял, таковы:
i регистронезависимый поиск
m многостроковый режим. По умолчанию PCRE ищет сопвадения с шаблоном только внутри одной строки, а символы «^» и «$» совпадают только с началом и концом всего текста. Когда этот параметр установлен, «^» и «$» совпадают с началом и концом отдельных строк.
s символ «.» (точка) совпадает и с переносом строки (по умолчанию — нет)
A привязка к началу текста
E заставляет символ «$» совпадать только с концом текста. Игнорируется, если установлен парамерт m.
U Инвертирует «жадность» для каждого квантификатора (если же после квантификатора стоит «?», этот квантификатор перестает быть «жадным»).
Естественно, регистр в параметрах имеет значение. Остальное о них можно прочесть в руководстве по php.
Теперь о функциях PCRE.
Функция preg_match в отличие от ereg ищет только первое совпадение. Если нужно найти все совпадения и как-то обработать их результаты (но не напрямую через preg_replace), нужно пользоваться preg_match_all. Параметры этой функции те же.
Из полезного отмечу функцию preg_quote, которая вставляет слэши перед всеми служебными символами (например, скобками, квадратными скобками и т.п.), чтобы те воспринимались буквально. Если у вас есть какой-либо ввод информации пользователем, и вы проверяете его через PCRE, лучше перед этим закомментировать служебные символы в пришедшей переменной (мало ли что он там напишет, это ведь по определению злобный хакер).
Это все, что я могу сказать про регулярные выражения. Дальше — только искусство комбинирования строк и написания алгоритмов.
Помнится, в одном из пришлых выпусков я описал рассыльщик почты на классах. Теперь я добавил туда хранение адресов в файлах и подтверждение подписки. Разумеется, различные проверки адресов, получение списка активных и тому подобное — все работает на PCRE. К сожалению, времени на тестирование и доводку не было, рассыльщик «сырой».
Аляповатый reg comp php. Man regcomp (3): функции регулярных выражений POSIX. Сравнение с регулярным выражением POSIX
Format
General description
Compiles the regular expression specified by pattern into an executable string of op-codes.
preg is a pointer to a compiled regular expression.
pattern is a pointer to a character string defining a source regular expression (described below).
cflags is a bit flag defining configurable attributes of compilation process: REG_EXTENDED Support extended regular expressions. REG_ICASE Ignore case in match. REG_NEWLINE Eliminate any special significance to the newline character. REG_NOSUB Report only success or fail in regexec(), that is, verify the syntax of a regular expression. If this flag is set, the regcomp() function sets re_nsub to the number of parenthesized sub-expressions found in pattern . Otherwise, a sub-expression results in an error.
The regcomp() function under z/OS XL C/C++ will use the definition of characters according to the current LC_SYNTAX category. The characters, [ , ] , < , >, | , ^ , and $ , have varying code points in different encoded character sets.
Regular expressions
The functions regcomp(), regerror(), regexec(), and regfree() use regular expressions in a similar way to the UNIX awk, ed, grep, and egrep commands.
The simplest form of regular expression is a string of characters with no special meaning. The following characters do have special meaning; they are used to form extended regular expressions: Symbol Description . The period symbol matches any one character except the terminal newline character. [ character – character ] The hyphen symbol, within square brackets, means “through”. It fills in the intervening characters according to the current collating sequence. For example, can be equivalent to or, with a different collating sequence, it can be equivalent to . [ string ] A string within square brackets specifies any of the characters in string . Thus , if compared to other strings, would match any that contained a, b, or c.
No assumptions are made at compile time about the actual characters contained in the range.
< m > < m ,> < m , u >Integer values enclosed in <> indicate the number of times to apply the preceding regular expression. m is the minimum number, and u is the maximum number. u must not be greater than RE_DUP_MAX (see limits.h).
If you specify only m , it indicates the exact number of times to apply the regular expression. < m ,>is equivalent to < m,u >. They both match m or more occurrences of the expression.
* The asterisk symbol indicates 0 or more of any characters. For example, [ a*e ] is equivalent to any of the following: 99ae9, aaaaae, a999e99. $ The dollar symbol matches the end of the string. (Use \n to match a newline character.) character + The plus symbol specifies one or more occurrences of a character. Thus, smith+ern is equivalent to, for example, smithhhern . [^ string ] The caret symbol, when inside square brackets, negates the characters within the square brackets. Thus [^abc] , if compared to other strings, would fail to match any that contains even one a, b, or c. ( expression )$ n Stores the value matched by the enclosed regular expression in the ( n +1) th ret parameter. Ten enclosed regular expressions are allowed. Assignments are made unconditionally. ( expression ) Groups a sub-expression allowing an operator, such as *, +, or .], to work on the sub-expression enclosed in parentheses. For example, (a*(cb+)*)$0 .
- Do not use multibyte characters.
- You can use the ] (right square bracket) alone within a pair of square brackets, but only if it immediately follows either the opening left square bracket or if it immediately follows [^. For example: –] matches the ] and – characters.
- All the preceding symbols are special . You precede them with \ to use the symbol itself. For example, a\.e is equivalent to a.e .
- You can use the – (hyphen) by itself, but only if it is the first or last character in the expression. For example, the expression —0] matches either the ] or else the characters – through 0. Otherwise, use \–.
Returned value
If successful, regcomp() returns 0.
If unsuccessful, regcomp() returns nonzero, and the content of preg is undefined.
Example
> int regcomp(regex_t * preg , const char * regex , int cflags ); int regexec(const regex_t * preg , const char * string , size_t nmatch , regmatch_t pmatch , int eflags ); size_t regerror(int errcode , const regex_t * preg , char * errbuf , size_t errbuf_size ); void regfree(regex_t * preg );
Description
POSIX regex compiling regcomp () is used to compile a regular expression into a form that is suitable for subsequent regexec () searches.
regcomp () is supplied with preg , a pointer to a pattern buffer storage area; regex , a pointer to the null-terminated string and cflags , flags used to determine the type of compilation.
All regular expression searching must be done via a compiled pattern buffer, thus regexec () must always be supplied with the address of a regcomp () initialized pattern buffer.
cflags may be the bitwise-or of one or more of the following: REG_EXTENDED Use POSIX Extended Regular Expression syntax when interpreting regex . If not set, POSIX Basic Regular Expression syntax is used. REG_ICASE Do not differentiate case. Subsequent regexec () searches using this pattern buffer will be case insensitive. REG_NOSUB Do not report position of matches. The nmatch and pmatch arguments to regexec () are ignored if the pattern buffer supplied was compiled with this flag set. REG_NEWLINE Match-any-character operators don»t match a newline.
A nonmatching list ([^. ] ) not containing a newline does not match a newline.
Match-beginning-of-line operator (^ ) matches the empty string immediately after a newline, regardless of whether eflags , the execution flags of regexec (), contains REG_NOTBOL .
Match-end-of-line operator ($ ) matches the empty string immediately before a newline, regardless of whether eflags contains REG_NOTEOL .
POSIX regex matching regexec () is used to match a null-terminated string against the precompiled pattern buffer, preg . nmatch and pmatch are used to provide information regarding the location of any matches. eflags may be the bitwise-or of one or both of REG_NOTBOL and REG_NOTEOL which cause changes in matching behavior described below. REG_NOTBOL The match-beginning-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above) This flag may be used when different portions of a string are passed to regexec () and the beginning of the string should not be interpreted as the beginning of the line. REG_NOTEOL The match-end-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above)
Byte offsets Unless REG_NOSUB was set for the compilation of the pattern buffer, it is possible to obtain match addressing information. pmatch must be dimensioned to have at least nmatch elements. These are filled in by regexec () with substring match addresses. The offsets of the subexpression starting at the i th open parenthesis are stored in pmatch[i] . The entire regular expression»s match addresses are stored in pmatch . (Note that to return the offsets of N subexpression matches, nmatch must be at least N+1 .) Any unused structure elements will contain the value -1.
The regmatch_t structure which is the type of pmatch is defined in .
Typedef struct < regoff_t rm_so; regoff_t rm_eo; >regmatch_t; Each rm_so element that is not -1 indicates the start offset of the next largest substring match within the string. The relative rm_eo element indicates the end offset of the match, which is the offset of the first character after the matching text.
POSIX error reporting regerror () is used to turn the error codes that can be returned by both regcomp () and regexec () into error message strings.
regerror () is passed the error code, errcode , the pattern buffer, preg , a pointer to a character string buffer, errbuf , and the size of the string buffer, errbuf_size . It returns the size of the errbuf required to contain the null-terminated error message string. If both errbuf and errbuf_size are nonzero, errbuf is filled in with the first errbuf_size — 1 characters of the error message and a terminating null byte («\0»).
POSIX pattern buffer freeing Supplying regfree () with a precompiled pattern buffer, preg will free the memory allocated to the pattern buffer by the compiling process, regcomp ().
Return Value
regcomp () returns zero for a successful compilation or an error code for failure.
regexec () returns zero for a successful match or REG_NOMATCH for failure.
Errors
The following errors can be returned by regcomp (): REG_BADBR Invalid use of back reference operator. REG_BADPAT Invalid use of pattern operators such as group or list. REG_BADRPT Invalid use of repetition operators such as using «*» as the first character. REG_EBRACE Un-matched brace interval operators. REG_EBRACK Un-matched bracket list operators. REG_ECOLLATE Invalid collating element. REG_ECTYPE Unknown character class name. REG_EEND Nonspecific error. This is not defined by POSIX.2. REG_EESCAPE Trailing backslash. REG_EPAREN Un-matched parenthesis group operators. REG_ERANGE Invalid use of the range operator, e.g., the ending point of the range occurs prior to the starting point. REG_ESIZE Compiled regular expression requires a pattern buffer larger than 64Kb. This is not defined by POSIX.2. REG_ESPACE The regex routines ran out of memory. REG_ESUBREG Invalid back reference to a subexpression.
Описание
Ищет парные значения string в регулярном выражении, указанном в pattern .
Если парные значения найдены для подстрок в круглых скобках pattern и функция вызывалась с третьим аргументом regs , то парные значения будут сохранены в элементах regs . $regs будет содержать подстроку, которая начинается с первой левой круглой скобки; $regs будет содержать подстроку, начинающуюся со второй скобки и т.д. $regs будет содержать копию string .
Поиск чуствителен к регистру.
Функция возвращает true, если парное значение для pattern было найдено в string, или false, если не было найдено парных значений или произошла ошибка.
Следующий код извлекает дату в ISO формате и выводит в формате DD.MM.YYYY:
Example 1. ereg() example
ereg_replace
Описание
Эта функция сканирует string на парные значения к pattern , затем заменяет найденный текст на replacement .
Если pattern содержит подстроки в круглых скобках, то replacement может содержать подстроки вида \\ цифра , которые будут заменены текстом, совпадающим с цифровой подстрокой в скобках; \\0 обработает все содержимое строки. Может быть использовано до 9 подстрок. Скобки могут быть сгруппированы, в этом случае они считаются по открывающим скобкам. Например, следующий код напечатет «This was a test» три раза:
Пример 1. ereg_replace()
$string = «This is a test»; echo ereg_replace(» is», » was», $string); echo ereg_replace(«()is», «\\1was», $string); echo ereg_replace(«(()is)», «\\2was», $string);
См. также , , и .
eregi
Описание
eregi_replace
Описание
split
Описание
Возвращает массив строк, каждая из которых является подстрокой строки, образованные разбитием этой строки на части, отделенные друг от друга pattern . Если произойдет ошибка, функция вернет false.
Для получения первых 5 полей из строки в /etc/passwd:
Эта функция может быть использована организации нечувствительного к регистру сравнения в продуктах, которые поддерживают только чувстуительные к регистру выражения.
#include
#include
int regcomp(regex_t * preg , const char * regex , int cflags );
int regexec(const regex_t * preg , const char * string , size_t nmatch ,
regmatch_t pmatch , int eflags );
size_t regerror(int errcode , const regex_t * preg , char * errbuf ,
size_t errbuf_size );
void regfree(regex_t * preg );
ОПИСАНИЕ
Компилирование регулярных выражений POSIX
regcomp () передаётся указатель на область хранения буферного шаблона preg , указатель на заканчивающуюся null строку regex и флаги cflags , используемые для определения типа компиляции.
Все поиски регулярных выражений должны выполняться с помощью скомпилированного буферного шаблона, поэтому regexec () должна всегда вызываться с адресом буферного шаблона, инициализированного функцией regcomp ().
Значение cflags может состоять из поразрядного or нуля или нескольких следующих значений:
REG_EXTENDED Использовать синтаксис расширенных регулярных выражений POSIX во время интерпретации regex . Если не включён этот флаг, то используется синтаксис простых регулярных выражений POSIX. REG_ICASE Не учитывать регистр. Последующие поиски regexec () с использованием данного буферного шаблона не будут зависеть от регистра. REG_NOSUB Не сообщать положение совпадений. Параметры nmatch и pmatch для regexec () игнорируются, если данный буферный шаблон был скомпилирован с этим включённым флагом. REG_NEWLINE Операторы совпадения с любым символом не совпадают с символом новой строки.
Список несовпадающих символов ([^. ] ) без символа новой строки не совпадает с новой строкой.
Оператор сравнения по началу строки (^ ) совпадает с пустой строкой сразу после новой строки независимо от того, что eflags , флаги выполнения regexec (), содержат REG_NOTBOL .
Оператор сравнения по концу строки ($) совпадает с пустой строкой до символа начала строки независимо от того, что eflags содержит REG_NOTEOL .
Сравнение с регулярным выражением POSIX
Байтовые смещения
Структура regmatch_t , являющаяся типом pmatch , определена в :
Каждый элемент rm_so , не равный -1, показывает начальное смещение следующего совпадения наибольшей подстроки внутри заданной строки. Относительный элемент rm_eo указывает на смещение конца совпадения, которое является первым символом после совпавшего текста.
Сообщение об ошибках POSIX
В regerror передаются: код ошибки errcode , буферный шаблон preg , указатель на символьный буфер строки errbuf и размер буфера строки errbuf_size . Функция возвращает размер errbuf , который требуется для сохранения сообщения об ошибке в виде строки, оканчивающейся null. Если и errbuf , и errbuf_size не равны нулю, то errbuf заполняется первыми errbuf_size — 1 символами сообщения об ошибке и завершается байтом null («\0»).
Освобождение буфера шаблона POSIX
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция regexec () возвращает ноль при совпадении или REG_NOMATCH , если совпадений не было.
ОШИБКИ
> int regcomp(regex_t * preg , const char * regex , int cflags ); int regexec(const regex_t * preg , const char * string , size_t nmatch , regmatch_t pmatch , int eflags ); size_t regerror(int errcode , const regex_t * preg , char * errbuf , size_t errbuf_size ); void regfree(regex_t * preg );
ОПИСАНИЕ
Компилирование регулярных выражений POSIX
regcomp () передаётся указатель на область хранения буферного шаблонаpreg , указатель на заканчивающуюся null строку regex и флагиcflags , используемые для определения типа компиляции.
Все поиски регулярных выражений должны выполняться с помощьюскомпилированного буферного шаблона, поэтому regexec () должна всегдавызываться с адресом буферного шаблона, инициализированного функциейregcomp ().
Значение cflags может состоять из поразрядного or нуля или несколькихследующих значений: REG_EXTENDED Использовать синтаксис расширенных регулярных выражений POSIX во времяинтерпретации regex . Если не включён этот флаг, то используется синтаксиспростых регулярных выражений POSIX. REG_ICASE Не учитывать регистр. Последующие поиски regexec () с использованиемданного буферного шаблона не будут зависеть от регистра. REG_NOSUB Не сообщать положение совпадений. Параметры nmatch и pmatch дляregexec () игнорируются, если данный буферный шаблон был скомпилирован сэтим включённым флагом. REG_NEWLINE Операторы совпадения с любым символом не совпадают с символом новой строки. Список несовпадающих символов ([^. ] ) без символа новой строки несовпадает с новой строкой. Оператор сравнения по началу строки (^ ) совпадает с пустой строкой сразупосле новой строки независимо от того, что eflags , флаги выполненияregexec (), содержат REG_NOTBOL . Оператор сравнения по концу строки ($) совпадает с пустой строкой до символаначала строки независимо от того, что eflags содержит REG_NOTEOL .
Сравнение с регулярным выражением POSIX
Байтовые смещения
Структура regmatch_t , являющаяся типом pmatch , определена в :
typedef struct <
regoff_t rm_so;
regoff_t rm_eo;> regmatch_t;
Каждый элемент rm_so , не равный -1, показывает начальное смещениеследующего совпадения наибольшей подстроки внутри заданнойстроки. Относительный элемент rm_eo указывает на смещение концасовпадения, которое является первым символом после совпавшего текста.
Сообщение об ошибках POSIX
В regerror передаются: код ошибки errcode , буферный шаблон preg ,указатель на символьный буфер строки errbuf и размер буфера строкиerrbuf_size . Функция возвращает размер errbuf , который требуется длясохранения сообщения об ошибке в виде строки, оканчивающейся null. Если иerrbuf , и errbuf_size не равны нулю, то errbuf заполняется первымиerrbuf_size — 1 символами сообщения об ошибке и завершается байтом null(aq\0aq).
Освобождение буфера шаблона POSIX
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция regexec () возвращает ноль при совпадении или REG_NOMATCH , еслисовпадений не было.
Тема 4. Регулярные выражения и функции обработки символьных строк
Цель: изучить эффективные методы обработки текстов.
Задачи:
- изучить принципы обработки текстов на PHP с использованием строковых функций;
- познакомиться с понятием регулярного выражения и научиться конструировать регулярные выражения с заданными свойствами;
- научиться применять построенные регулярные выражения.
Оглавление
4.1. Строковые функции PHP
В PHP существует очень много встроенных функций по работе со строками. Большая часть названий этих функций сведена в табл. 4.1.
Имя функции
Назначение
Выводит значение переменной или выражения
Print _ r
Echo
Выводит значения списка строковых переменных
Chr
Получение символа с указанным кодом
Substr
Str_repeat
Получение строки из повторяющихся значений
Str_pad
Дополнение строки другой строкой до заданной длины
Chunk_split
Фрагментирование строки (вставляется последовательность разделителей)
Strtok
получение строки по частям
Explode
Разделение строки в массив (на части по указанному разделителю)
Implode
Или join
Объединение элементов массива в строку с добавлением заданного разделителя
Strlen
Crypt
Strcmp
Сравнение 2 строк c учетом регистра
Strcasecmp
Сравнение строк без учета регистра
Strchr
Синоним strstr
Поиск первого вхождения символа в строку
Strpos
Определение первой позиции фрагмента в строке
Strrpos
Определение последней позиции фрагмента в строке
Ltrim
Удаление начальных пробелов
Rtrim или chop
Удаление конечных пробелов
Trim
Удаление начальных и конечных пробелов
Strrev
Strtoupper
Преобразование в верхний регистр
Strtolower
Преобразование в нижний регистр
Strtr
Замена указанных символов во всей строке
Str_replace
Замена фрагментов строки
Substr_replace
Замена части строки
Addslashes
Добавление обратных экранирующих слэшей перед спец. символами
Stripslashes
Удаление обратных слэшей
Convert_cyr_string
Конвертация строки из одной кодировки кириллицы в другую
Parse_url
Разделение строки url на ее компоненты
str_pad()
Выравнивает строку до определенной длины заданными символами и возвращает отформатированную строку
strlen (string строка)
Определение длины строки
Strcspn().
Возвращает длину первого сегмента строки1, содержащего символы, отсутствующие в строке2
substr_count()
Возвращает количество вхождений подстроки в заданную строку
substr_count (string строка, string подстрока)
substr_replace()
Заменяет часть строки, которая начинается с заданной позиции
substr_replace (string строка, string замена, int начало [, int длина ])
Параметры начало и длина задаются по определенным правилам:
- если параметр начало положителен, замена начинается с заданной позиции;
- если параметр начало отрицателен, замена начинается с позиции (длина строки — начало);
- если параметр длина положителен, заменяется фрагмент заданной длины;
- если параметр длина отрицателен, замена завершается в позиции (длина строки — длина)
nl2br()
Заменяет все символы новой строки (\n) эквивалентными конструкциями HTML
.
Описание данных функций дано подробно в документации.
Возможности эффективной организации, поиска и распространения информации давно представляли интерес для специалистов в области компьютерных технологий. Поскольку информация в основном представляет собой текст, состоящий из алфавитно-цифровых символов, разработка средств поиска и обработки информации по шаблонам, описывающим текст, стала предметом серьезных теоретических исследований. Поиск по шаблону позволяет не только находить определенные фрагменты текста, но и заменять их другими фрагментами.
4.2. Механизмы поиска по шаблону
Данные механизмы решают четыре основные задачи:
- поиск строк, в точности совпадающих с заданным шаблоном;
- поиск фрагментов строк, совпадающих с заданным шаблоном;
- замену строк и подстрок по шаблону;
- поиск строк, с которыми заданный шаблон не совпадает.
Для решения задач лингвистического анализа текста был предложен механизм регулярных выражений. Регулярные выражения — это не изобретение программистов, а формальный язык математики, который в настоящий момент эффективно применяется в различных языках и средах программирования. В PHP присутствуют 2 группы функций по работе с регулярными выражениями, одна группы ориентирована на язык Perl, в котором эти механизмы впервые нашли эффективную поддержку, а вторая — это группа функций, ориентированная на стандарт открытых систем POSIX. Демократичность языка PHP предполагает, что разработчики могут использовать тот комплект функций, который им кажется более удобным.
Регулярные выражения лежат в основе всех современных технологий поиска по шаблону. Регулярное выражение представляет собой последовательность простых и служебных символов, описывающих искомый текст и принципы его преобразования.
4.3. Синтаксис регулярных выражений (POSIX)
Структура регулярных выражений POSIX чем-то напоминает структуру типичных математических выражений — различные элементы (операторы) объединяются друг с другом и образуют более сложные выражения. Однако именно смысл объединения элементов делает регулярные выражения таким мощным и выразительным средством. Возможности не ограничиваются поиском литерального текста (например, конкретного слова или числа); вы можете провести поиск строк с разной семантикой, но похожим синтаксисом — например, всех тегов HTML в файле.
Оператор | (вертикальная черта) проверяет совпадение одной из нескольких альтернатив.
Квадратные скобки ([ ]) имеют особый смысл в контексте регулярных выражений — они означают «любой символ из перечисленных в скобках».
- [ 0-9] — совпадает с любой десятичной цифрой от 0 до 9;
- [a-z] — совпадает с любым символом нижнего регистра от а до z;
- [A-Z] — совпадает с любым символом верхнего регистра от А до Z;
- [a -Z] — совпадает с любым символом нижнего или верхнего регистра от а до Z.
4.3.1. Квантификаторы
Существует особый класс служебных символов, обозначающих количество повторений отдельного символа или конструкции, заключенной в квадратные скобки. Эти служебные символы (+, * и <. >) называются квантификаторами. Принцип их действия проще всего пояснить на примерах:
- р+ означает один или несколько символов р, стоящих подряд;
- р* означает ноль и более символов р, стоящих подряд;
- р? означает ноль или один символ р;
- р <2>означает два символа р, стоящих подряд;
- р <2,3>означает от двух до трех символов р, стоящих подряд;
- р <2,>означает два и более символов р, стоящих подряд.
4.3.2. Прочие служебные символы
Служебные символы $ и ^ совпадают не с символами, а с определенными позициями в строке. Например, выражение р$ означает строку, которая завершается символом р, а выражение ^р — строку, начинающуюся с символа р.
Конструкция [^a-zA-Z] совпадает с любым символом, не входящим в указанные интервалы (a-z и A-Z).
Служебный символ. (точка) означает «любой символ». Например, выражение р.р совпадает с символом р, за которым следует произвольный символ, после чего опять следует символ р.
Объединение служебных символов приводит к появлению более сложных выражений.
Рассмотрим несколько примеров:
- ^.<2>$ — любая строка, содержащая ровно два символа;
- (.*) — произвольная последовательность символов, заключенная между и (вероятно, тегами HTML для вывода жирного текста);
- p(hp)* — символ р, за которым следует ноль и более экземпляров последовательности hp (например, phphphp).
Иногда требуется найти служебные символы в строках вместо того, чтобы использовать их в описанном специальном контексте. Для этого служебные символы экранируются обратной косой чертой (\). Например, для поиска денежной суммы в долларах можно воспользоваться выражением \$[0-9]+, т. е. «знак доллара, за которым следует одна или несколько десятичных цифр». Обратите внимание на обратную косую черту перед $. Возможными совпадениями для этого регулярного выражения являются $42, $560.
Стандартные интервальные выражения (символьные классы)
Для удобства программирования в стандарте POSIX были определены некоторые стандартные интервальные выражения, также называемые символьными классами (character classes). Символьный класс определяет один символ из заданного интервала — например, букву алфавита или цифру:
- [[:alpha:]] — алфавитный символ (aA-zZ);
- [[:digit:]]-цифра (0-9);
- [[:alnum:]] — алфавитный символ (aA-zZ) или цифра (0-9);
- [[:space:]] — пропуски (символы новой строки, табуляции и т. д.).
4.4. Функции РНР для работы с регулярными выражениями (POSIX-совместимые)
В настоящее время РНР поддерживает семь функций поиска с использованием регулярных выражений в стиле POSIX:
Описания этих функций приведено далее.
Функция еrеg() ищет в заданной строке совпадение для шаблона. Если совпадение найдено, возвращается TRUE, в противном случае возвращается FALSE. Синтаксис функции ereg():
int ereg (string шаблон, string строка [, array совпадения]) |
Поиск производится с учетом регистра алфавитных символов. Пример использования ereg() для поиска в строках доменов.соm:
$is_com — ereg(«(\.)(com$)», $email):
// Функция возвращает TRUE, если $email завершается символами «.com»
// В частности, поиск будет успешным для строк
// «www.wjgilmore.com» и «someemail@apress.com»
Обратите внимание: из-за присутствия служебного символа $ регулярное выражение совпадает только в том случае, если строка завершается символами.com. Например, оно совпадет в строке «www.apress.com», но не совпадет в строке «www.apress.com/catalog».
Необязательный параметр совпадения содержит массив совпадений для всех подвыражений, заключенных в регулярном выражении в круглые скобки.
ereg_replace()
Функция ereg_replace() ищет в заданной строке совпадение для шаблона и заменяет его новым фрагментом. Синтаксис функции ereg_replace():
string ereg_replace (string шаблон, string замена, string строке)
Функция ereg_replace() работает по тому же принципу, что и ereg(), но ее возможности расширены от простого поиска до поиска с заменой. После выполнения замены функция возвращает модифицированную строку. Если совпадения отсутствуют, строка остается в прежнем состоянии. Функция ereg_replace(), как и еrеg(), учитывает регистр символов. Ниже приведен простой пример, демонстрирующий применение этой функции:
$copy_date = «Copyright 2005»:
$copy_date = ereg_replace(«([0-9]+)». «2006», $copy_date);
print $copy_date: // Выводится строка «Copyright 2006»
У средств поиска с заменой в языке РНР имеется одна интересная возможность — возможность использования обратных ссылок на части основного выражения, заключенные в круглые скобки. Обратные ссылки похожи на элементы необязательного параметра-массива совпадения функции еrеg() за одним исключением: обратные ссылки записываются в виде \0, \1, \2 и т. д., где \0 соответствует всей строке, \1 — успешному совпадению первого подвыражения и т. д. Выражение может содержать до 9 обратных ссылок. В следующем примере все ссылки на URL в тексте заменяются работающими гиперссылками:
$url = «Apress (http://www.apress.com»);
eregi()
Функция eregi() ищет в заданной строке совпадение для шаблона. Синтаксис функции eregi():
int eregi (string шаблон, string строка [, array совпадения])
Поиск производится без учета регистра алфавитных символов. Функция eregi() особенно удобна при проверке правильности введенных строк (например, паролей). Использование функции eregi() продемонстрировано в следующем примере:
print «Invalid password! Passwords must be from 8 through 10 characters in length.»;
// В результате выполнения этого фрагмента выводится сообщение об ошибке.
// поскольку длина строки «abc» не входит в разрешенный интервал от 8 до 10 символов.
eregi_replace()
Функция eregi_replасе() работает точно так же, как ereg_replace(), за одним исключением: поиск производится без учета регистра символов. Синтаксис функции ereg_replace():
string eregi_replace (string шаблон, string замена, string строка)
split()
Функция split() разбивает строку на элементы, границы которых определяются по заданному шаблону. Синтаксис функции split():
array split (string шаблон, string строка [, int порог])
Необязательный параметр порог определяет максимальное количество элементов, на которые делится строка слева направо. Если шаблон содержит алфавитные символы, функция spl it() работает с учетом регистра символов. Следующий пример демонстрирует использование функции split() для разбиения канонического IP-адреса на триплеты:
$ip = «123.345.789.000»; // Канонический IP-адрес
$iparr = split («\.», $ip) // Поскольку точка является служебным
// символом. ее необходимо экранировать.
print «$iparr[0]
«; // Выводит «123»
print «$iparr[1]
«; // Выводит «456»
print «$iparr[2]
«; // Выводит «789»
print «$iparr[3]
«; // Выводит «000»
spliti ()
Функция spliti() работает точно так же, как ее прототип split(), за одним исключением: она не учитывает регистра символов. Синтаксис функции spliti():
array spliti (string шаблон, string строка [, int порог ])
Разумеется, регистр символов важен лишь в том случае, если шаблон содержит алфавитные символы. Для других символов выполнение spliti() полностью аналогично split().
sql_regcase()
Вспомогательная функция sql_regcase() заключает каждый символ входной строки в квадратные скобки и добавляет к нему парный символ. Синтаксис функции sql_regcase():
string sql_regcase (string строка)
Если алфавитный символ существует в двух вариантах (верхний и нижний регистры), выражение в квадратных скобках будет содержать оба варианта; в противном случае исходный символ повторяется дважды. Функция sql_regcase() особенно удобна при использовании РНР с программными пакетами, поддерживающими регулярные выражения в одном регистре. Пример преобразования строки функцией sql_regcase():
$version = «php 4.0»;
Выводится строка [Pp][Hh][Pp][ ][44][..][00]
4.5. Синтаксис регулярных выражений в стиле Perl
Perl давно считается одним из самых лучших языков обработки текстов. Синтаксис Perl позволяет осуществлять поиск и замену даже для самых сложных шаблонов. Разработчики РHР сочли, что не стоит заново изобретать уже изобретенное, а лучше сделать знаменитый синтаксис регулярных выражений Perl доступным для пользователей РНР. Так появились функции для работы с регулярными выражениями в стиле Perl.
Диалект регулярных выражений Perl не так уж сильно отличается от диалекта POSIX. В сущности, синтаксис регулярных выражений Perl является отдаленным потомком реализации POSIX, вследствие чего синтаксис POSIX почти совместим с функциями регулярных выражений стиля Perl. Функции обработки регулярных выражений Perl-совместимые работают в 10-20 раз быстрее. Поэтому при обработке больших и сложных текстов рекомендуют использовать именно их.
Рассмотрим общие принципы регулярных выражений Perl на простом примере:
Обратите внимание: строка программа заключена между двумя косыми чертами. Как и в стандарте POSIX, вы можете создавать более сложные шаблоны при помощи квантификаторов:
Этот шаблон совпадает с последовательностью програм, за которой могут следовать дополнительные символы м. Например, совпадения будут обнаружены в строках программ, программм. Рассмотрим пример использования квантификатора с ограничением:
Шаблон совпадает с символом 14, за которым следуют от 2 до 4 экземпляров символа Х. К числу потенциальных совпадений относятся строки 14ХХ092, 14ХХХХ77 и 14ХХХХl.
В регулярных выражениях Perl могут использоваться все квантификаторы, упомянутые в предыдущем разделе для регулярных выражений POSIX.
Метасимволы
Одной из интересных особенностей Perl является использование метасимволов при поиске. Метасимвол представляет собой алфавитный символ с префиксом \ — признаком особой интерпретации следующего символа. Например, метасимвол \d может использоваться при поиске денежных сумм:
Комбинация \d обозначает любую цифру. Конечно, в процессе поиска часто возникает задача идентификации алфавитно-цифровых символов, поэтому в Perl для них был определен метасимвол \w:
Этот шаблон совпадает с конструкциями, заключенными в угловые скобки, — например, тегами HTML. Кстати, метасимвол \W имеет прямо противоположный смысл и используется для идентификации символов, не являющихся алфавитно-цифровыми.
Еще один полезный метасимвол, \b, совпадает с границами слов:
/ sql \b/ — это последовательность строк, начинающаяся с sql.
Поскольку метасимвол границы слова расположен справа от текста, этот шаблон совпадет в строках sql 1 и sqlnew или newsql, но не в строке. Противоположный метасимвол, \В, совпадает с чем угодно, кроме границы слова:
/ sql \B/ — символы sql должны находиться только не на границе слов.
Шаблон совпадает в таких строках, как PLsql _1 и PLSQL _ Oracle, но не совпадает в строке PLSQL.
Модификаторы
Модификаторы заметно упрощают работу с регулярными выражениями. Впрочем, модификаторов много, и в табл. 4.2 приведены лишь наиболее интересные из них. Модификаторы перечисляются сразу же после регулярного выражения — например, /string/i.
Моди-фикатор
Описание
Фрагмент текста интерпретируется как состоящий из нескольких «логических строк». По умолчанию специальные символы ^ и $ совпадают только в начале и в конце всего фрагмента. При включении «многострочного режима» при помощи модификатора m^ и $ будут совпадать в начале и в конце каждой логической строки внутри фрагмента
По смыслу противоположен модификатору m — при поиске фрагмент интерпретируется как одна строка, а все внутренние символы новой строки игнорируются
Поиск выполняется без учета регистра символов
4.6. Функции РНР для работы с регулярными выражениями (Perl-совместимые)
В РНР существует пять функций поиска по шаблону с использованием Perl-совместимых регулярных выражений:
preg_match()
Функция preg_ m atch() ищет в заданной строке совпадение для шаблона. Если совпадение найдено, возвращается TRUE, в противном случае возвращается FALSE. Синтаксис функции:
int preg_ m atch (string шаблон, string строка [, array совпадения>)
При передаче необязательного параметра совпадения массив заполняется совпадениями различных подвыражений, входящих в основное регулярное выражение. В следующем примере функция preg_match() используется для проведения поиска без учета регистра:
$lin е = «Vi is the greatest word processor ever created!»;
// Выполнить поиск слова «Vi» без учета регистра символов:
if (preg_match(«/\bVi\b\i», $line, $matcn)):print «Cовпадение найдено !»;
// Команда if в этом примере возвращает TRUE
preg_match_all()
Функция preg_match_all() находит все совпадения шаблона в заданной строке.
Синтаксис функции preg_match_all():
Int preg_match_all (string шаблон, string строка, array совпадения [, int порядок ])
Порядок сохранения в массиве совпадения текста, совпавшего с подвыражениями, определяется необязательным параметром порядок. Этот параметр может принимать два значения:
- PREG_PATTERN_ORDER — используется по умолчанию, если параметр порядок не указан. Порядок, определяемый значением PREG_PATTERN_ORDER, на первый взгляд выглядит не совсем логично: первый элемент (с индексом 0) содержит массив совпадений для всего регулярного выражения, второй элемент (с индексом 1) содержит массив всех совпадений для первого подвыражения в круглых скобках и т. д.;
- PREG_SET_ORDER — порядок сортировки массива несколько отличается от принятого по умолчанию. Первый элемент (с индексом 0) содержит массив с текстом, совпавшим со всеми подвыражениями в круглых скобках для первого найденного совпадения. Второй элемент (с индексом 1) содержит аналогичный массив для второго найденного совпадения и т. д.
Следующий пример показывает, как при помощи функции preg_match_al() найти весь текст, заключенный между тегами HTML . :
$user_info = «Name: Rasmus Lerdorf
Title: PHP Guru«;
preg_match_all («/(.*) /U», Suserinfo. $pat_array);
print $pat_array[0][0].»
«.pat_array[0][l].»\n»:
Результат :
Rasmus Lerdorf
PHP Guru
preg_replace()
Функция preg_repl ace() работает точно так же, как и ereg_replасе(), за одним исключением того, что регулярные выражения могут использоваться в обоих параметрах: в шаблоне и в замене. Синтаксис функции preg_replace():
mixed preg_replace (mixed шаблон, mixed замена, mixed строка [, int порог])
Необязательный параметр порог определяет максимальное количество замен в строке. Интересный факт: параметры шаблон и замена могут представлять собой массивы. Функция preg_replace() перебирает элементы обоих массивов и выполняет замену по мере их нахождения.
preg_split()
Функция preg_spl it() аналогична split() за одним исключением — параметр шаблон может содержать регулярное выражение. Синтаксис функции preg_split():
array preg_split (string шаблон, string строка [, int порог [, int флаги]])
Необязательный параметр порог определяет максимальное количество элементов, на которые делится строка. В следующем примере функция preg_split() используется для выборки информации из переменной.
$user_info=»+wj+++Gilmore+++++wjgi l more@hotmail.com
+++++++ Columbus +++OH»;
$fields = preg_split(«/\+<1.>/», $user_info);
Регулярные выражения
Понятие регулярного выражения
Регулярное выражение ( regular expression , сокращенно РВ ) – это технология, которая позволяет задать шаблон и осуществить поиск данных, соответствующих этому шаблону, в заданном тексте, представленном в виде строки.
Кроме того, с помощью регулярных выражений можно изменить и удалить данные, разбить строку по шаблону на подстроки и многое другое.
Одно из распространенных применений РВ – это проверка строки на соответствие каким-либо правилам. Например, следующее РВ предназначено для проверки того, что строка содержит корректный e-mail– адрес :
Выглядит, конечно, жутко, но зато работает. И если уметь пользоваться этим механизмом виртуозно, то жить становится легче.
Вернемся к нашему определению РВ . В нем несколько раз повторяется термин » шаблон «. Что это такое? В принципе, интуитивно понятно, но попробуем все же пояснить.
Давайте подумаем, что представляет собой корректный e-mail– адрес . Это набор букв, цифр и символов подчеркивания, после которых идет специальный символ «собака» @ , затем еще один такой же набор, содержащий имя сервера, точку ( .) и две или три буквы, указывающие на зону домена, к которой принадлежит почтовый ящик (ru, com , org и т.д.). Приведенное выше РВ формализует данное описание на языке, понятном компьютеру. И описывает не какой-то конкретный электронный адрес , а все возможные корректные электронные адреса. Таким образом, производится формальное задание множества правильных e-mail’ов с помощью шаблона регулярного выражения . Другие примеры шаблонов – это шаблоны MS Word и html-формы .
Механизм регулярных выражений задает правила построения шаблонов и осуществляет поиск данных по этому шаблону в указанной строке.
В дальнейшем изложении термины РВ и » шаблон » часто будут использоваться как синонимы, но важно понимать, что это не совсем одно и то же. Шаблон задает какой-то тип данных , а РВ – это механизм, который производит поиск и включает в себя шаблон и опции поиска, а также задает язык написания шаблонов.
Регулярные выражения в PHP
Регулярные выражения пришли из UNIX и Perl. Как упоминалось выше, с помощью регулярных выражений можно искать и изменять текст, разбивать строку на подстроки и т.д. В PHP существуют такие удобные и мощные средства работы со строками, как explode ( разбиение строки на подстроки), strstr (нахождение подстроки), str_replace (замена всех вхождений подстроки). Возникает вопрос – зачем придумывать что-то еще?
Основное преимущество РВ заключается в том, что они позволяют организовать более гибкий поиск , т.е. найти то, о чем нет точного знания, но есть примерное представление . Например, нужно найти все семизначные номера телефонов, встречающиеся в тексте. Мы не ищем какой-то заранее известный нам номер телефона, мы знаем только, что искомый номер состоит из семи цифр. Для этого можно воспользоваться следующим РВ :
В PHP существует два различных механизма для обработки регулярных выражений : POSIX-совместимые и Perl-совместимые (сокращенно PCRE ). Их синтаксис во многом похож, однако Perl-совместимые регулярные выражения более мощные и к тому же работают намного быстрее. Начиная с версии PHP 4.2.0, PCRE входят в набор базовых модулей и подключены по умолчанию. POSIX-совместимые РВ включены по умолчанию только в версию PHP для Windows .
Основные функции для работы с Perl-совместимыми регулярными выражениями : preg_match (pattern, string, result[, flags]) и preg_match_all (pattern, string, result, [flags]) , где:
pattern – шаблон регулярного выражения ;
string – строка, в которой производится поиск ;
result – содержит массив результатов (нулевой элемент массива содержит соответствие всему шаблону, первый – первому «захваченному» подшаблону и т.д.);
flags – необязательный параметр , определяющий то, как упорядочены результаты поиска.
Эти функции осуществляют поиск по шаблону и возвращают информацию о том, сколько раз произошло совпадение. Для preg_match() это 0 (нет совпадений) или 1 , поскольку поиск прекращается, как только найдено первое совпадение. Функция preg_match_all() производит поиск до конца строки и поэтому находит все совпадения. Все точные совпадения содержатся в первом элементе массива result у каждой из этих функций (для preg_match_all() этот элемент – тоже массив ).
Про » захват » элементов будет рассказано в разделе, посвященном подвыражениям .
Аналогом preg_match является булева функция POSIX -расширения ereg (string pattern, string string [, array regs])
Функция ereg() возвращает TRUE , если совпадение найдено, и FALSE – в противном случае.
Приводимые далее примеры можно тестировать на перечисленных функциях. Например, так:
LXXXIX. Функции регулярных выражений
(POSIX Extended)
Примечание: PHP поддерживает также регулярные выражения в синтаксисе Perl через использование функций PCRE. Эти функции поддерживают нежадное совпадение, утверждения, условные субпатэрны и некоторые другие возможности, не поддерживаемые синтаксисом регулярных выражений POSIX-extended.
Предупреждение! | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
. | соответствует одному любому символу |
[что-то] | Соответствует любому единичномусимволу из числа заключённых в скобки. При этом:Символ «-» интерпретируется буквально только в том случае, если он расположен непосредственно после открывающей или перед закрывающей скобкой: [abc-] или [-abc]. В противном случае, он обозначает интервал символов.Например, [abc] соответствует «a», «b» или «c». [a-z] соответствует буквам нижнего регистра латинского алфавита. Эти обозначения могут и сочетаться: [abcq-z] соответствует a, b, c, q, r, s, t, u, v, w, x, y, z.Чтобы установить соответствие символам «[» или «]», достаточно, чтобы закрывающая скобка была первым символом после открывающей: [][ab] соответствует «]», «[», «a» или «b».Если значение в квадратных скобах предварено символом ^, то значение выражения соответствует единичному символу из числа тех, которых нет в скобках. Например, [^abc] соответствует любому символу, кроме «a», «b» или «c». [^a-z] соответствует любому символу, кроме символов нижнего регистра в латинском алфавите. |
^ | Соответствует началу текста (или началу любой строки, если режим построчный). |
$ | Соответствует концу текста (или концу любой строки, если режим построчный). |
\(\) или ( ) | Объявляет «отмеченное подвыражение» (сгруппированное выражение), которое может быть использовано позже (см. следующий элемент: \n). «Отмеченное подвыражение» также является «блоком». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша, в расширенном и Perl символ \ — не нужен. |
\n | Где n — это цифра от 1 до 9; соответствует n-му отмеченному подвыражению (например (abcd)\0, то есть символы abcd отмечены нулем). Эта конструкция теоретически нерегулярна, она не была принята в расширенном синтаксисе регулярных выражений. |
* |
. Выражение, заключённое в «\(» и «\)» и сопровождаемое «*», следует считать неправильным. В некоторых случаях, оно соответствует нулю или более вхождений строки, которая была заключена в скобки. В других, оно соответствует выражению, заключённому в скобки, учитывая символ «*». |
\<x,y\> | Соответствует последнему (предстоящему) блоку, встречающемуся не менее x и не более y раз. Например, «a\<3,5\>» соответствует «aaa», «aaaa» или «aaaaa». В отличие от других операторов, этот (в традиционном синтаксисе) требует бэкслеша. |
.* | Обозначение любого количества любых символов между двумя частями регулярного выражения. |
Метасимволы нам помогают использовать различные соответствия. Но как же представить метасимвол обычным символом, то есть символ [ (квадратная скобка) значением квадратной скобки? Просто:
- необходимо предварить (экранировать) метасимвол (. * + \ ? [ ] < >) обратным слешем. Например \. или\[
Для упрощения задания некоторых наборов символов, их объединили в т.н. классы и категории символов . POSIX стандартизовал объявление некоторых классов и категорий символов, как показано в следующей таблице:
POSIX класс | аналогично | обозначение |
[:upper:] | [A-Z] | символы верхнего регистра |
[:lower:] | [a-z] | символы нижнего регистра |
[:alpha:] | [A-Za-z] | символы верхнего и нижнего регистра |
[:alnum:] | [A-Za-z0-9] | цифры, символы верхнего и нижнего регистра |
[:digit:] | [0-9] | цифры |
[:xdigit:] | [0-9A-Fa-f] | шестнадцатеричные цифры |
[:punct:] | [. …] | знаки пунктуации |
[:blank:] | [ \t] | пробел и TAB |
[:space:] | [ \t\n\r\f\v] | символы пропуска |
[:cntrl:] | символы управления | |
[:graph:] | [^ \t\n\r\f\v] | символы печати |
[:print:] | [^\t\n\r\f\v] | символы печати и символы пропуска |
В regex есть такое понятие как:
Жадность regex
Постараюсь описать как можно понятней. Допустим, мы хотим найти все HTML теги в каком-то тексте. Локализовав задачу, мы хотим найти значения заключенные между , вместе с этими самыми скобками. Но мы знаем, что теги имеют разную длину и самих тегов, как минимум штук 50. Перечислять их все , заключив в метасимволы [] — задача слишком трудоемкая. Но мы знаем, что у нас есть выражение .* (точка звездочка), характеризующее любое число любых символов в строке. С помощью данного выражения мы попытаемся найти в тексте (
Итак, Как создать RA >
) все значения между . В результате, этому выражению будет соответствовать ВСЯ строка. почему, потому что регекс — ЖАДЕН и старается захватить ЛЮБОЕ ВСЕ количество символов между , соответственно вся строка, начиная p>Итак. и заканчивая .
> будет принадлежать данному правилу!
Надеюсь, на примере понятно что такое жадность. Чтобы избавиться от данной жадности, можно пойти по следующему пути:
- учесть символы, не соответствующие желаемому образцу (например: ]*> для вышеописанного случая)
- избавить от жадности, добавив определении квантификатора, как нежадного:
- *? — «не жадный» («ленивый») эквивалент *
- +? — «не жадный» («ленивый») эквивалент +
? — «не жадный» («ленивый») эквивалент
- .*? — «не жадный» («ленивый») эквивалент .*
Все вышенаписанное хочу дополнить синтаксисом расширенных регулярных выражений:
Регулярные выражения в POSIX аналогичны традиционному Unix-синтаксису, но с добавлением некоторых метасимволов:
Плюс указывает на то, что предыдущий символ или группа может повторяться один или несколько раз. В отличие от звёздочки, хотя бы одно повторение обязательно.
Знак вопроса делает предыдущий символ или группу необязательной. Другими словами, в соответствующей строке она может отсутствовать, либо присутствовать ровно один раз.
Вертикальная черта разделяет альтернативные варианты регулярных выражений. Один символ задаёт две альтернативы, но их может быть и больше, достаточно использовать больше вертикальных чёрточек. Необходимо помнить, что этот оператор использует максимально возможную часть выражения. По этой причине, оператор альтернативы чаще всего используется внутри скобок.
Также было отменено использование обратной косой черты: \ <…\>становится <…>и \(…\) становится (…).
В завершение поста, приведу некоторые примеры использования regex:
Аляповатый reg comp php. Man regcomp (3): функции регулярных выражений POSIX. Сравнение с регулярным выражением POSIX
Format
General description
Compiles the regular expression specified by pattern into an executable string of op-codes.
preg is a pointer to a compiled regular expression.
pattern is a pointer to a character string defining a source regular expression (described below).
cflags is a bit flag defining configurable attributes of compilation process: REG_EXTENDED Support extended regular expressions. REG_ICASE Ignore case in match. REG_NEWLINE Eliminate any special significance to the newline character. REG_NOSUB Report only success or fail in regexec(), that is, verify the syntax of a regular expression. If this flag is set, the regcomp() function sets re_nsub to the number of parenthesized sub-expressions found in pattern . Otherwise, a sub-expression results in an error.
The regcomp() function under z/OS XL C/C++ will use the definition of characters according to the current LC_SYNTAX category. The characters, [ , ] , < , >, | , ^ , and $ , have varying code points in different encoded character sets.
Regular expressions
The functions regcomp(), regerror(), regexec(), and regfree() use regular expressions in a similar way to the UNIX awk, ed, grep, and egrep commands.
The simplest form of regular expression is a string of characters with no special meaning. The following characters do have special meaning; they are used to form extended regular expressions: Symbol Description . The period symbol matches any one character except the terminal newline character. [ character – character ] The hyphen symbol, within square brackets, means “through”. It fills in the intervening characters according to the current collating sequence. For example, can be equivalent to or, with a different collating sequence, it can be equivalent to . [ string ] A string within square brackets specifies any of the characters in string . Thus , if compared to other strings, would match any that contained a, b, or c.
No assumptions are made at compile time about the actual characters contained in the range.
< m > < m ,> < m , u >Integer values enclosed in <> indicate the number of times to apply the preceding regular expression. m is the minimum number, and u is the maximum number. u must not be greater than RE_DUP_MAX (see limits.h).
If you specify only m , it indicates the exact number of times to apply the regular expression. < m ,>is equivalent to < m,u >. They both match m or more occurrences of the expression.
* The asterisk symbol indicates 0 or more of any characters. For example, [ a*e ] is equivalent to any of the following: 99ae9, aaaaae, a999e99. $ The dollar symbol matches the end of the string. (Use \n to match a newline character.) character + The plus symbol specifies one or more occurrences of a character. Thus, smith+ern is equivalent to, for example, smithhhern . [^ string ] The caret symbol, when inside square brackets, negates the characters within the square brackets. Thus [^abc] , if compared to other strings, would fail to match any that contains even one a, b, or c. ( expression )$ n Stores the value matched by the enclosed regular expression in the ( n +1) th ret parameter. Ten enclosed regular expressions are allowed. Assignments are made unconditionally. ( expression ) Groups a sub-expression allowing an operator, such as *, +, or .], to work on the sub-expression enclosed in parentheses. For example, (a*(cb+)*)$0 .
- Do not use multibyte characters.
- You can use the ] (right square bracket) alone within a pair of square brackets, but only if it immediately follows either the opening left square bracket or if it immediately follows [^. For example: –] matches the ] and – characters.
- All the preceding symbols are special . You precede them with \ to use the symbol itself. For example, a\.e is equivalent to a.e .
- You can use the – (hyphen) by itself, but only if it is the first or last character in the expression. For example, the expression —0] matches either the ] or else the characters – through 0. Otherwise, use \–.
Returned value
If successful, regcomp() returns 0.
If unsuccessful, regcomp() returns nonzero, and the content of preg is undefined.
Example
> int regcomp(regex_t * preg , const char * regex , int cflags ); int regexec(const regex_t * preg , const char * string , size_t nmatch , regmatch_t pmatch , int eflags ); size_t regerror(int errcode , const regex_t * preg , char * errbuf , size_t errbuf_size ); void regfree(regex_t * preg );
Description
POSIX regex compiling regcomp () is used to compile a regular expression into a form that is suitable for subsequent regexec () searches.
regcomp () is supplied with preg , a pointer to a pattern buffer storage area; regex , a pointer to the null-terminated string and cflags , flags used to determine the type of compilation.
All regular expression searching must be done via a compiled pattern buffer, thus regexec () must always be supplied with the address of a regcomp () initialized pattern buffer.
cflags may be the bitwise-or of one or more of the following: REG_EXTENDED Use POSIX Extended Regular Expression syntax when interpreting regex . If not set, POSIX Basic Regular Expression syntax is used. REG_ICASE Do not differentiate case. Subsequent regexec () searches using this pattern buffer will be case insensitive. REG_NOSUB Do not report position of matches. The nmatch and pmatch arguments to regexec () are ignored if the pattern buffer supplied was compiled with this flag set. REG_NEWLINE Match-any-character operators don»t match a newline.
A nonmatching list ([^. ] ) not containing a newline does not match a newline.
Match-beginning-of-line operator (^ ) matches the empty string immediately after a newline, regardless of whether eflags , the execution flags of regexec (), contains REG_NOTBOL .
Match-end-of-line operator ($ ) matches the empty string immediately before a newline, regardless of whether eflags contains REG_NOTEOL .
POSIX regex matching regexec () is used to match a null-terminated string against the precompiled pattern buffer, preg . nmatch and pmatch are used to provide information regarding the location of any matches. eflags may be the bitwise-or of one or both of REG_NOTBOL and REG_NOTEOL which cause changes in matching behavior described below. REG_NOTBOL The match-beginning-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above) This flag may be used when different portions of a string are passed to regexec () and the beginning of the string should not be interpreted as the beginning of the line. REG_NOTEOL The match-end-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above)
Byte offsets Unless REG_NOSUB was set for the compilation of the pattern buffer, it is possible to obtain match addressing information. pmatch must be dimensioned to have at least nmatch elements. These are filled in by regexec () with substring match addresses. The offsets of the subexpression starting at the i th open parenthesis are stored in pmatch[i] . The entire regular expression»s match addresses are stored in pmatch . (Note that to return the offsets of N subexpression matches, nmatch must be at least N+1 .) Any unused structure elements will contain the value -1.
The regmatch_t structure which is the type of pmatch is defined in .
Typedef struct < regoff_t rm_so; regoff_t rm_eo; >regmatch_t; Each rm_so element that is not -1 indicates the start offset of the next largest substring match within the string. The relative rm_eo element indicates the end offset of the match, which is the offset of the first character after the matching text.
POSIX error reporting regerror () is used to turn the error codes that can be returned by both regcomp () and regexec () into error message strings.
regerror () is passed the error code, errcode , the pattern buffer, preg , a pointer to a character string buffer, errbuf , and the size of the string buffer, errbuf_size . It returns the size of the errbuf required to contain the null-terminated error message string. If both errbuf and errbuf_size are nonzero, errbuf is filled in with the first errbuf_size — 1 characters of the error message and a terminating null byte («\0»).
POSIX pattern buffer freeing Supplying regfree () with a precompiled pattern buffer, preg will free the memory allocated to the pattern buffer by the compiling process, regcomp ().
Return Value
regcomp () returns zero for a successful compilation or an error code for failure.
regexec () returns zero for a successful match or REG_NOMATCH for failure.
Errors
The following errors can be returned by regcomp (): REG_BADBR Invalid use of back reference operator. REG_BADPAT Invalid use of pattern operators such as group or list. REG_BADRPT Invalid use of repetition operators such as using «*» as the first character. REG_EBRACE Un-matched brace interval operators. REG_EBRACK Un-matched bracket list operators. REG_ECOLLATE Invalid collating element. REG_ECTYPE Unknown character class name. REG_EEND Nonspecific error. This is not defined by POSIX.2. REG_EESCAPE Trailing backslash. REG_EPAREN Un-matched parenthesis group operators. REG_ERANGE Invalid use of the range operator, e.g., the ending point of the range occurs prior to the starting point. REG_ESIZE Compiled regular expression requires a pattern buffer larger than 64Kb. This is not defined by POSIX.2. REG_ESPACE The regex routines ran out of memory. REG_ESUBREG Invalid back reference to a subexpression.
Описание
Ищет парные значения string в регулярном выражении, указанном в pattern .
Если парные значения найдены для подстрок в круглых скобках pattern и функция вызывалась с третьим аргументом regs , то парные значения будут сохранены в элементах regs . $regs будет содержать подстроку, которая начинается с первой левой круглой скобки; $regs будет содержать подстроку, начинающуюся со второй скобки и т.д. $regs будет содержать копию string .
Поиск чуствителен к регистру.
Функция возвращает true, если парное значение для pattern было найдено в string, или false, если не было найдено парных значений или произошла ошибка.
Следующий код извлекает дату в ISO формате и выводит в формате DD.MM.YYYY:
Example 1. ereg() example
ereg_replace
Описание
Эта функция сканирует string на парные значения к pattern , затем заменяет найденный текст на replacement .
Если pattern содержит подстроки в круглых скобках, то replacement может содержать подстроки вида \\ цифра , которые будут заменены текстом, совпадающим с цифровой подстрокой в скобках; \\0 обработает все содержимое строки. Может быть использовано до 9 подстрок. Скобки могут быть сгруппированы, в этом случае они считаются по открывающим скобкам. Например, следующий код напечатет «This was a test» три раза:
Пример 1. ereg_replace()
$string = «This is a test»; echo ereg_replace(» is», » was», $string); echo ereg_replace(«()is», «\\1was», $string); echo ereg_replace(«(()is)», «\\2was», $string);
См. также , , и .
eregi
Описание
eregi_replace
Описание
split
Описание
Возвращает массив строк, каждая из которых является подстрокой строки, образованные разбитием этой строки на части, отделенные друг от друга pattern . Если произойдет ошибка, функция вернет false.
Для получения первых 5 полей из строки в /etc/passwd:
Эта функция может быть использована организации нечувствительного к регистру сравнения в продуктах, которые поддерживают только чувстуительные к регистру выражения.
#include
#include
int regcomp(regex_t * preg , const char * regex , int cflags );
int regexec(const regex_t * preg , const char * string , size_t nmatch ,
regmatch_t pmatch , int eflags );
size_t regerror(int errcode , const regex_t * preg , char * errbuf ,
size_t errbuf_size );
void regfree(regex_t * preg );
ОПИСАНИЕ
Компилирование регулярных выражений POSIX
regcomp () передаётся указатель на область хранения буферного шаблона preg , указатель на заканчивающуюся null строку regex и флаги cflags , используемые для определения типа компиляции.
Все поиски регулярных выражений должны выполняться с помощью скомпилированного буферного шаблона, поэтому regexec () должна всегда вызываться с адресом буферного шаблона, инициализированного функцией regcomp ().
Значение cflags может состоять из поразрядного or нуля или нескольких следующих значений:
REG_EXTENDED Использовать синтаксис расширенных регулярных выражений POSIX во время интерпретации regex . Если не включён этот флаг, то используется синтаксис простых регулярных выражений POSIX. REG_ICASE Не учитывать регистр. Последующие поиски regexec () с использованием данного буферного шаблона не будут зависеть от регистра. REG_NOSUB Не сообщать положение совпадений. Параметры nmatch и pmatch для regexec () игнорируются, если данный буферный шаблон был скомпилирован с этим включённым флагом. REG_NEWLINE Операторы совпадения с любым символом не совпадают с символом новой строки.
Список несовпадающих символов ([^. ] ) без символа новой строки не совпадает с новой строкой.
Оператор сравнения по началу строки (^ ) совпадает с пустой строкой сразу после новой строки независимо от того, что eflags , флаги выполнения regexec (), содержат REG_NOTBOL .
Оператор сравнения по концу строки ($) совпадает с пустой строкой до символа начала строки независимо от того, что eflags содержит REG_NOTEOL .
Сравнение с регулярным выражением POSIX
Байтовые смещения
Структура regmatch_t , являющаяся типом pmatch , определена в :
Каждый элемент rm_so , не равный -1, показывает начальное смещение следующего совпадения наибольшей подстроки внутри заданной строки. Относительный элемент rm_eo указывает на смещение конца совпадения, которое является первым символом после совпавшего текста.
Сообщение об ошибках POSIX
В regerror передаются: код ошибки errcode , буферный шаблон preg , указатель на символьный буфер строки errbuf и размер буфера строки errbuf_size . Функция возвращает размер errbuf , который требуется для сохранения сообщения об ошибке в виде строки, оканчивающейся null. Если и errbuf , и errbuf_size не равны нулю, то errbuf заполняется первыми errbuf_size — 1 символами сообщения об ошибке и завершается байтом null («\0»).
Освобождение буфера шаблона POSIX
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция regexec () возвращает ноль при совпадении или REG_NOMATCH , если совпадений не было.
ОШИБКИ
> int regcomp(regex_t * preg , const char * regex , int cflags ); int regexec(const regex_t * preg , const char * string , size_t nmatch , regmatch_t pmatch , int eflags ); size_t regerror(int errcode , const regex_t * preg , char * errbuf , size_t errbuf_size ); void regfree(regex_t * preg );
ОПИСАНИЕ
Компилирование регулярных выражений POSIX
regcomp () передаётся указатель на область хранения буферного шаблонаpreg , указатель на заканчивающуюся null строку regex и флагиcflags , используемые для определения типа компиляции.
Все поиски регулярных выражений должны выполняться с помощьюскомпилированного буферного шаблона, поэтому regexec () должна всегдавызываться с адресом буферного шаблона, инициализированного функциейregcomp ().
Значение cflags может состоять из поразрядного or нуля или несколькихследующих значений: REG_EXTENDED Использовать синтаксис расширенных регулярных выражений POSIX во времяинтерпретации regex . Если не включён этот флаг, то используется синтаксиспростых регулярных выражений POSIX. REG_ICASE Не учитывать регистр. Последующие поиски regexec () с использованиемданного буферного шаблона не будут зависеть от регистра. REG_NOSUB Не сообщать положение совпадений. Параметры nmatch и pmatch дляregexec () игнорируются, если данный буферный шаблон был скомпилирован сэтим включённым флагом. REG_NEWLINE Операторы совпадения с любым символом не совпадают с символом новой строки. Список несовпадающих символов ([^. ] ) без символа новой строки несовпадает с новой строкой. Оператор сравнения по началу строки (^ ) совпадает с пустой строкой сразупосле новой строки независимо от того, что eflags , флаги выполненияregexec (), содержат REG_NOTBOL . Оператор сравнения по концу строки ($) совпадает с пустой строкой до символаначала строки независимо от того, что eflags содержит REG_NOTEOL .
Сравнение с регулярным выражением POSIX
Байтовые смещения
Структура regmatch_t , являющаяся типом pmatch , определена в :
typedef struct <
regoff_t rm_so;
regoff_t rm_eo;> regmatch_t;
Каждый элемент rm_so , не равный -1, показывает начальное смещениеследующего совпадения наибольшей подстроки внутри заданнойстроки. Относительный элемент rm_eo указывает на смещение концасовпадения, которое является первым символом после совпавшего текста.
Сообщение об ошибках POSIX
В regerror передаются: код ошибки errcode , буферный шаблон preg ,указатель на символьный буфер строки errbuf и размер буфера строкиerrbuf_size . Функция возвращает размер errbuf , который требуется длясохранения сообщения об ошибке в виде строки, оканчивающейся null. Если иerrbuf , и errbuf_size не равны нулю, то errbuf заполняется первымиerrbuf_size — 1 символами сообщения об ошибке и завершается байтом null(aq\0aq).
Освобождение буфера шаблона POSIX
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция regexec () возвращает ноль при совпадении или REG_NOMATCH , еслисовпадений не было.