AllInfo
Main: Info Blog Temp Mail


unix 2011-01-25 13-41-31

Основы регулярных выражений

Что такое регулярные выражения?

Регулярные выражения (regular expression, regexp, регэксп) - механизм, позволяющий задать шаблон для строки и осуществить поиск данных, соответствующих этому шаблону в заданном тексте. Регэкспы используют специальный синтаксис и концепции, с тем чтобы получить информацию из строки. Многие языки программирования имеют определенную поддержку regexes, поскольку от них только польза. Шаблоны используются не только для подтверждения того, что определенная структура существует в строке, но также что регулярные выражения могут быть использованы для физического извлечения соответствующих частей и их использования в вашем PHP-коде. Хотя, это не упоминается в данном руководстве, но имейте в виду, потому что более подробней будет об этом в следующем учебном пособии в этой серии.

Насколько они отличаются от строковых функций?

Регулярные строковые функции поиска как функции strpos() и str_replace() очень ограничены в том, что они могут реально сделать. Они прекрасно подходят для замены одного или двух символов, или изменения ‘ham’ в ‘turkey’ в одном составе, но это все, что все они могут делать. Если вы хотите увидеть, содержит ли строка все числа (и, возможно, запятые, что разделяют цифры), вы должны создать несколько замысловатую обработку стандартной операции, наподобие того, как показано в следующих строках:

<?php
$string = "731,489,392,222";
foreach (str_split($string) as $char) {
if (!is_numeric($char) or $str != ',') {
$bad = true;
}
}
if (!$bad) {
....
}
?>
Вот, где сила regexes вступает в игру. Они предоставляют удивительные возможности в плане анализа строк для некоторых шаблонов и поиска.

Зачем беспокоиться? Я могу делать разбор подпрограмм (parsing), что сделает работу хорошо.

Этот вопрос на самом деле довольно часто задается пользователеями, которые впервые столкнулись с Regex. Регулярные выражения изучить довольно витьевато, и у них очень сложный синтаксис, но они являются одним из наиболее эффективных способов получения PHP обработки данных так, как именно вы хотите. Иногда, виды данных и шаблонов, которые регулярные выражения могут разобрать, просто не представляются возможным эмулировать со строковыми функциями. Regexes могут быть достаточно сложными на первый взгляд, но, когда они разбиты на отдельные части, и их синтакс проанализирован, они, на самом деле, довольно просты.

Что ж, теперь пришло время, узнать вам, как создавать регулярные выражения самим.

Примечание: Это руководство охватывает только синтаксис регулярного выражения. Фактические поиск по шаблону, замена, и обработка результатов в PHP будут рассмотрены в последующих статьях. Кроме того, данное руководство охватывает набор Perl-совместимых регулярных выражений (PCRE), по причинам, которые будут обсуждаться позднее.

Создание шаблонов
Прежде чем мы начнем интерпретировать синтаксис регулярного выражения, то было бы неплохо узнать, во-первых, как шаблон выглядит. Строка всегда начинается с символа разделителя, за которым следует непосредственно регулярное выражение, затем еще один символ разделителя и потом необязательный список модификаторов, который будет обсуждаться позже в этом руководстве. Наиболее часто используется в качестве разделителя знак /, но чаще целесообразнее использовать некоторые скрытые символы, которые никогда не завершают ни один из ваших шаблонов (например, `, #, или !). Для большинства из примеров в этом учебнике, я буду использовать / как ограничитель, просто потому, что это привычно, но вы можете использовать любой символ. Теперь, когда у нас есть разделители, давайте рассмотрим один из самых простых шаблонов.

/abc/
Если простые буквы приводятся в регулярном выражении, это интерпретируется как только то, что это - простые буквы. Этот шаблон будет искать ЛЮБУЮ строку, содержащую ‘abc’ в том же порядке. Не очень полезно, но оно иллюстрирует некоторые основные принципы. Обратите внимание, как часть, которую нужно найти (’abc’) содержится в разделителях? Вот так каждый шаблон должен быть отформатирован, иначе он просто не будет работать.

Больше, чем простые буквы (литералы)

Уметь помещать простые буквые внутри / / здорово, но вы для этого могли бы просто использовать ваш верный strpos(). В тех случаях, когда реальная сила регулярных выражений приходит вместе с метасимволами. Эти символы не просто символы, это символы специального значения. У некоторых метасимволов так много значений, что они на самом деле являются причиной значений других символов. Метасимволы регулярных выражений:

| . ( ) [ ] { } ^ $ + ?
Для того, чтобы на самом деле эти символы точно совпали, вы должны добавить слеш перед ними. Так, в инструкции, в целях точного совпадения с (.), вы можете использовать следующий шаблон:

/./
Заметьте, вновь используются разделители (/ /) и обратный слэш, который идет до метасимвола, чтобы “де-метасимволить” его. Но интересно отметить то, что в целях точного совпадения с обратным слэшем, вы должны поставить 2 обратных слэша, поскольку он сам по себе является метасимволом.

//
Как метасимволы работают

Этот раздел будет полностью посвящен углубленному разъяснению каждого из метасимволов, и как они действуют, когда используется шаблон.

Всеобъемлющий метасимвол (.)

У метасимвола (.) на самом деле довольно простая концепция. Метасимвол (.) соответствует ЛЮБОМУ символу, за исключением символа перевода строки (
), но он может быть изменен (объясним позже). Простая демонстрация, как он работает:

/c.t/
Этот шаблон будет соответствовать cat, cut, cbt, cet, czt, c4t и так далее, но не caat потому, что существует только одна точка (.) в структуре. Важно отметить, что метасимвол (.) совпадет только с одним символом, до тех пор, пока не введены количественные показатели - квантификаторы (т.н. quantifiers).

Якорные метасимволы (^ $)

Иногда вам необходимо на самом деле убедиться в том, что строка начинается или заканчивается определенным символом. Вот где потребуются метасимволы ^ и $

Символ ^ указывает, что искомый текст должен находиться в начале строки. Он фактически не совпадает с каким-то буквенным символом, но вместо этого, он совпадает с границей. Чтобы убедиться в том, что строка начинается с Z, можно применить следующий шаблон:

/^z/
Символ $ по сути то же самое, что и символ ^, за исключением того, что он указывает, что искомый текст должен находиться в конце строки. Чтобы убедиться в том, что строка заканчивается на g, нужно использовать:

/g$/
Обратите внимание, как $ идет после g, в отличие от шаблона с ^. Это объясняется тем, что шаблон буквально говорит механизму Regex “g находится в конце строки”, а не наоборот. В самом деле, по другому никак не может быть, потому что после конца строки символов нет. Единственным способом, когда символы могут появляться после $, если у вас есть регулярные выражения в многострочном режиме. О нем будет подробно рассказано позже в этом руководстве, но имейте в виду, что значение ^ и $ иногда может меняться.

Эти два метасимвола также могут быть использованы одновременно в шаблоне, а это происходит частенько. Лучше это рассмотреть на примере:

/^abc$/
Этот шаблон довольно прост. Он говорит, что строка должна начинаться, затем совпадать с ‘abc’, и потом также совпадать в конце строки. В принципе, строка должна быть “abc” в целях соответствия.

Группировка метасимволов (())

Символы круглых скобок “(” и “)”, используемые в концепции, вызывает группировку. Символ “(” начинает группу, а символ “)” заканчивает его. Каждый открывающий “(” должен иметь закрывающий “)”. Так вступает в работу не только захват подстроки, который будет использоваться позже, но и единственный способ заставить другие метасимволы искать больше, чем по одному символу. Как правило, каждый символ и сам является подмаской, по которой другие метасимволы могут делать поиск, но скобки все меняют. Они позволяют создавать более “сложные” подмаски. Любая ссылка на слово подмаски теперь означает что, это единичный символ подмаски или группа в скобках.

Любые примеры сейчас показывать довольно бессмысленно, но вот один:

/(abc)/
Cейчас он будет совпадать с таким же регэкспом, как и /abc/, но не будет в других примерах после объяснения других метасимволов.

Другое использование группировки заключается в создании обратных ссылок, которые фактически позволяют использовать уже найденные результаты поиска для дальнейшей обработки основного регулярного выражения. Здесь пригождается подстановка и более расширенный синтаксис, но пока просто возьмите это на заметку.

Количественные метасимволы - квантификаторы (* +? ())

Квантификаторы являются одними из наиболее важных метасимволов регулярных выражений. Они диктуют, как часто определенная буква (или группа!) должна повторяться определенное количество раз. Они, безусловно, делают шаблоны более динамичными, чем просто совпадениия одного символа.

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

/ab*c/
Выражение /ab*c/ найдет строки ‘ac’, ‘abc’, ‘abbc’ и т.д. Если вы хотите, чтобы * нашел более, чем один символ, вы должны использовать группировку метасимволов, которые были упомянуты выше (я уже говорил, что они еще пригодятся!):

/a(bcd)*/
Оно найдет строки: abcd, abcdbcd, abcdbcdbcd, и так далее.

Квантификатор плюс ‘+’ действует подобно звездочке *, за исключением того, что он диктует, количество предыдущий подмаски должно быть один или более раз. Он говорит движку, что должна появиться определенная подмаска, и если это произойдет, то это может повторить до бесконечности.

/c.+t/
Здесь вы можете увидеть одну из реальной силы квантификаторов. Они могут использоваться с любым символом, в том числе и с метасимволом точка, как в данном случае. Этот шаблон будет находить строки: cat, caaaaat, cbbbajsduasuut, cjkallskt и т.д.

Квантификатор вопросительный знак ? делает предыдущую подмаску необязательной, означает, что символ может как присутствовать, так и нет, но при этом не может повторяться более одного раза.

/a(bcd)?e/
Выражение найдет строки: или abcde, или ae, потому что вопросительный знак ? делает фрагмент шаблоны (bcd) необязательным.

Метасимволы фигурные скобки ‘{’ и ‘}’ используются для того, чтобы указать более точное количество подмаски. Они имеют несколько различных вариантов синтаксиса для выполнения различных вещей. Внутри скобок через запятую перечисляются минимальное и максимальное количество повторений символа, например:

/a(bcd){2}e/ #находит abcdbcde, потому что {2} указывает ТОЧНО 2 сопоставления
/a(bcd){2,3}e/ # найдет abcdbcde или abcdbcdbcde, потому что {2,3} означает 2 или 3 matches, включительно
/a(bcd){2,}e/ # найдет любую строку с a, 'bcd' повторяющиеся как МИНИМУМ 2 раза, и e. {2,} представляет минимум
Кстати, вы не можете просто указать максимум без минимума (например, {, 2}). Если вы хотите максимальное значение повторений, можно сказать так (1, макс). Кроме того, интересно отметить, что все остальные квантификаторы в какой-то мере могут быть представлены в условиях {}:

/a(bcd)*e/ равен /a(bcd){0,}e/
/a(bcd)+e/ равен /a(bcd){1,}e/
/a(bcd)?e/ равен /a(bcd){0,1}e/
Квантификаторы *, + и? зачастую предпочитаемы для удобочитаемости.

Важно отметить, что без использования якорных метасимволов, ^ и $, шаблон будет возвратит совпадения в строке, даже если присутствуют другие символы. Например, в следующей строке:

drtabcabcabcpdl
Следующий шаблон действительно возвратит положительное совпадение:

/ab*c/
Если вы хотите быть уверенным, что строка содержит ТОЛЬКО определенный шаблон, вы должны заякорить его:

/^ab*c$/
Теперь шаблон будет искать только а, любое число в и с.

Метасимвол альтернатив (|)

Метасимвол вертикальная черта | в основном эквивалентна ИЛИ в PHP (вот почему она выглядит похоже на ||). Она говорит интерпретатору, что нужно найти по шаблону символы, разделенные |, начиная слева направо. В мгновение он находит что-то из альтернатив, останавливается и продолжает поиск по шаблону. Вы будете чаще всего использовать метасимволы группировки, чтобы указать вертикальной черте |, с какими строками фактически работать, в противном случае она может привести к весьма неожиданным результатам. Метасимвол альтернатив действует в самых внутренних скобках.

/(yes)|(no)/
Это будет соответствовать или “да”, или “нет” во всей ее полноте, но оно может иметь различные результаты, если осталась бы вне группировке. Это строго рекомендуется для отслеживания того, как вы группируете выражения, поскольку это может полностью изменить как интерпретатор выглядит по маске. Просто, чтобы помочь вам визуализировать один пример, когда группировку альтернатив важно отслеживать, я покажу вам следующую маску:

/prob|n|r|l|ate/
Этот шаблон будет действительно находить строки ‘prob’, ‘n’, ‘r’, ‘l’, или ‘ate’. Если вы хотели бы найти probate, pronate, prorate, и prolate то, что нужно использовать:

/pro(b|n|r|l)ate/
Метасимволы символьного класса ( [ ] )

Ах, наконец, мы достигли символьных классов. Это чрезвычайно мощное понятее Regex для изучения и понимания, прочитайте этот раздел несколько раз.

Символьные классы говорят интерпретатору найти какой-либо символ, содержащихся в квадратных скобках [ ], как один символ. Я думаю, что было бы лучше начать с базового примера, такого, как:

/c[aeiou]t/
Этот regex будет искать cat, cet, cit, cot, и cut, потому что [aeiou] класс содержит эти символы между С и Т. Если бы я изменил символьный класс [au], то он нашел только cat и cut. Теперь, это не означает, что вы не смогли выполнить то же самое, с метасимволами альтернатив, но они становятся очень громоздким и большее количество “суперской” функциональности символьного класса (которая будет рассмотрены сразу же после этого) не может быть достигнуто с ними. Предыдущий шаблон можно было бы записать в виде:

/c(a|e|i|o|u)t/
Но кто на самом деле захочет печатать это?

Отличительная сторона символьного класса - диапазоны. Внутри класса символов, вы можете задать диапазон для поиска (отделяются друг от друга минусом - ). Если вы хотели бы найти строки, содержащие любые 5 цифр, вы можете записать этот шаблон:

/([0-9]{5})/
Приемлемые диапазоны a-z, AZ, 0-9 и некоторые другие диапазоны, связанные с фактическим “значением” некоторых символов, но это немного продвинутый уровень. Еще одна важная вещь, которую стоит упомянуть так это то, что диапазон может быть “состыкован” внутри одного класса. Следующий пример иллюстрирует это.

/^[a-zA-Z0-9_]+$/
Этот шаблон будет диктовать, что строка должна содержать какое-то количество только алфавитно-цифровых символов и нижней черты (_), в связке с якорями (^ и $), квантификаторами (+) и символьным классом ([A-Za-Z0 - 9_]).

Существуют также “кратчайший путь” для символьных классов, который интерпретатор понимает автоматически. Они заключаются в следующем:

/d/ #находит любую цифру
/D/ #находит любую не цифру (любой символ кроме символов 0-9)
/w/ #находит "словесный" символ (символ, который используется в словах. Обычно все буквы, все цифры и знак подчеркивания ('_')), [a-zA-Z0-9_])
/W/ #находит все, кроме символов, определяемых метасимволом w
/s/ #находит пустой символ (обычно пробел, символ табуляции и перевод строки)
/S/ #находит непустой символ (все, кроме символов, определяемых метасимволом s)
Эти ярлыки могут быть использованы как внутри, так и за их фактическим символьным классом, то есть они могут появляться в любом месте шаблона.

Таким образом, с этими знаниями, мы можем сократить этот шаблон “найти 5 цифр” в:

/d{5}/
Изучите эти выражения, они вам очень помогут, если вы на самом деле будете писать шаблоны самостоятельно. В качестве примера использования ярлыка внутри символьного класса:

/^[a-zA-Zs]+$/
Этот шаблон будет сопостовляться строке, содержащей a-z, A-Z, и любые пустым символам.

Существуют также некоторые другие маленькие нюансы символьного класса, с чем вам действительно надо познакомиться. Если символ класса начинаются с ^, то это уже не означает начало строки, а вместо этого он выступает в качестве восклицательного знака ! (НЕ) в PHP. Он отрицает символьный класс.

/c[^au]t/
Этот шаблон будет сопостовляться строке, содержащей cbt, c$t, c!t, crt, etc, но не cat и cut.

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

В заключении о метасимволах

Это просто итог всего того, что было рассказано выше о метасимволах (все еще есть некоторый расширенный синтаксис с участием нескольких метасимволов, но по этому поводу не стоит беспокоиться). Помните, что эти метасимволы можно использовать все сразу в шаблоне, что позволяет полностью контролировать поиск по строке.

Жадность квантификаторов
Я чувствовал, что эта тема заслуживает своей собственной страницы. При использовании квантификаторов, существует концепция, известная как жадность и лень, которая может привести к большой путанице новичков в регулярных выражениях.

Что такое жадность?
Жадность - это то, как движок интерпретирует “юрисдикцию” квантификаторов. Позвольте мне создать быстрый сценарий:

У вас есть строка ‘exasperate’. Вы выполняете следующий шаблон:

/e(.*)e/
Хотите верьте, хотите нет, но это шаблон (.*) фактически совпаде т с xasperat вместо xasp как вы, возможно, подумали. Обычное поведение для квантификаторов заключается в том, чтобы пожирать так много символов, как это возможно. Следовательно, жадность. Он хочет захватить столько символов, сколько может сойти ему с рук, и они все еще могут совпадать. Вот почему он выходит вправо мимо второго е в exasperate и продолжает сопоставлять дальше, пока он не достигнет последней возможной е.

Как заставить сопоставления быть ленивыми (нежадными)
Это поведение по умолчанию можно изменить, добавив вопросительный знак ? после квантификаторов. Для того, чтобы сопоставлять (.*) ‘xasp‘ в предыдущем случае, вы можете использовать:

/e(.*?)e/
Этот шаблон говорит движку, чтобы он принял меры, необходимые для успеха в поиске, и ничего более. Другой способ для того, чтобы вы могли увидеть ответный удар по жадности, является использование негативного символьного класса, но это работает, если нужно оргадить от жадности только один символ. Например, в HTML-шаблоне поиска, вы хотели бы получить текст в определенном теге <p>, который следует за другим <p>, как в этом крошечном фрагменте:

<p id="test">p1</p> <p id="test">p2</p>
Вы можете написать ваш шаблон, как этот:

!<p id="test">(.+)</p>!
Это не удивительно, что быстро поглощаются ОБА тега <p>, даже если он действительно не соответствуют закрывающему тегу. Движок не осознает этого, и ему нравится быть жадным, поэтому он так поступает. Вы можете изменить шаблон:

!<p id="test">(.+?)</p>!
Или, вы можете использовать один негативный символьный класс и сказать:

!<p id="test">([^<]+)</p>!
Последний пример зачастую немного быстрее, в плане скорости исполнения, но может быть более сложным для понимания.

Другая существенная польза от негативного символьного класса - когда вы пытаетесь получить информацию из определенных атрибутов тегов HTML. Следующий шаблон будет получать атрибут SRC тега IMG.

!<img(.+?)src="([^"]+)"(.*?) />!
Теперь это действительно сложный шаблон, но если вы разберете его на части, он окажется на самом деле довольно простым. Во-первых, вы хотите найти буквально шаблон ‘<img’. Затем, вы сопоставляете любое количество символов (нежадно), до тех пор, пока не достигнете атрибута SRC. Затем, вы используете негативный символьный класс ([^"]+), чтобы захватить все, вплоть до конечной кавычки “. Тогда у вас есть какое-либо количество символов, за которыми следует стандартный способ закрытия тега IMG.

Концепция жадности и лени очень важна, чтобы знать, как достичь желаемых результатов, которые мы реально получим с помощью шаблонов поиска (это уже тема следующей статьи, на самом деле). Перечитайте эту страницу столько раз, сколько потребуется, пока вы полностью не поймете эту концепцию.

Модификаторы шаблонов
Помните, как я говорил о причинах, почему регулярное выражение должно иметь разделитель? Он не только содержит регулярные выражения, но также позволяет использовать специальные модификаторы шаблонов, которые идут после закрывающего разделителя. Это позволит вам изменять то, как движок фактически просматривает ваш шаблон. В этом разделе я собираюсь пройтись по каждому модификатору, которые широко используются в regexes. В следующем учебном пособии, после рассказа о подстановке, я пройдусь по модификаторам, которые работают для замены, поскольку существуют некоторые различия.

Модификатор нечувствительности к регистру - The Insensitivity Modifier (i)
Если вы используете //i модификатор, нечувствительность к регистру включена для всего регулярного выражения. Возьмем, к примеру, следующее регулярное выражение:

/super/
Оно будет соответствовать ’super’, но не “SuPeR” или “SUPER”. Для того, чтобы выражение находило все возможные варианты шаблона, можно использовать множество альтернатив или некоторые умные символьные классы, или вы могли бы просто применить модификатор i:

/super/i
Обратите внимание, как i идет ПОСЛЕ закрывающего разделителя.

Модификатор сопоставления переноса строки (s)
Прежде, когда я объяснял про всеобъемлющий модификатор - точка (.), я сказал, что он не будет сопоставлять с переносами строки. Модификатор //s позволяет ему сделать это. Рассмотрим следующий сценарий.
У вас есть файл со следующим содержимым:

something
//start
STUFF!
some more stuff...
//end
Если вы хотели искать по всему, что находится между этими двумя комментариями (//start и //end), вы должны написать ваш Regex так:

!//start(.+?)//end!s
Теперь, уделите пристальное внимание тому, что я сделал. С тех пор как мне на самом деле необходимо было использовать символ / в моем шаблоне, сейчас уже нет смысла использовать его в качестве разделителя, потому что тогда он должен быть замаскирован всякий раз, как я использовал его (///start(.+?)//end/s). Это невероятно трудно читать, так как я использовал восклицательный знак в качестве разделителя. Модификатор s в конце позволяет шаблону сопоставлять все прочее, что находится между двумя комментариями, даже если они расположены на разных строках.

Модификатор многострочного режима (m)
Этот модификатор немного странен, если честно. Он действительно изменяет поведение этих двух якорных метасимволов (^ и $). Как правило, они указывают, где искать - в начале и конце строки, соответственно, но с модификатором //m они в действительности сопоставляют сразу после переноса строки (
). Вы, вероятно, зачастую не смогли бы и себя найти с помощью него, если только бы вы не хотели, чтобы каждая строка в файле имела, например, только 5 цифр в строке:

/^d{5}$/m
Модификатор режима без учёта пробелов (х)
Это более продвинутый модификатор, и он заставляет движок игнорировать ЛЮБЫЕ пробелы внутри Regex. Он позволяет фактически создать комментарии внутри Regex и свободно располагает пространство, чтобы облегчить задачу глазам. Например, следующее регулярное выражение (которое иллюстрирует некоторые концепции, про которые я еще не рассказал, но не беспокойтесь об этом, это только для того, чтобы продемонстрировать свободный интервал):

/(wS+)(s+)+/i
Может быть записано как:

/
/b #word boundary
(wS+) #word "chunk"
(
s+ #whitespace
 #same word "chunk"
) + #repeat if necessary
 #boundary
/xi
Конечно, так более удобно читать, правда? Комментарии могут быть помещены в конец строки со знаком #, и затем ваши замечания.

Где найти другие модификаторы
Вы всегда можете посмотреть http://us3.php.net/manual/en/reference.pcre.pattern.modifiers.php с тем, чтобы увидеть каждый поддерживаемый модификатор. Многие из них не используются, поэтому я счел излишним показать их вам сейчас, но если когда-либо придется их искать, вы можете сделать это на этой странице. Помните, что всегда можно найти руководство, если вы в чем-то сомневаетесь. Кроме того, имейте в виду, что есть на самом деле модификатор, который может быть использован только при подстановке, и я его представлю в следующем учебном пособии, поскольку вы не сможете еще пока по-настоящему мысленно представить то, что он способен.

PCRE против POSIX
Это в большей степени техническая часть учебника, но я чувствовал, что про это нужно рассказать. Есть фактически две “разновидности”, если так можно выразиться, регулярных выражений, поддерживаемых PHP. Это Perl-совместимые регулярные выражения (PCRE) и регулярные выражения POSIX Extended. PCRE гораздо более мощный, чем POSIX, он может делать гораздо больше вещей, к которым POSIX просто не может даже приблизиться. Они очень похожи в синтаксисе (для большей части, пока вы не получите продвинутый синтаксис, который будет в последующем), но PCRE имеет гораздо больше функций. Я думаю, что сейчас я бы отметил некоторые из этих различий здесь, чтобы вы знали, зачем вы должны наверняка изучить PCRE вдобавок к POSIX.

Бинарные данные
PCRE может быть использован в двоичных данных, тогда как POSIX не может. PCRE может работать со всеми из отдельных байтов и символов любой строки, будь то текст или бинарник, что является огромным плюсом.

Скорость
POSIX может быть намного медленнее, чем PCRE. Я не собираюсь вдаваться в подробности, так как лучше я не буду путать людей.

Модификаторы и разделитель
POSIX не поддерживает модификаторы в своих шаблонах, но они также не используют и разделители, как PCRE. Единственная опция, когда вы работаете с POSIX, это нечувствительность к регистру, но он даже использует совершенно иную функцию, которую я вряд ли назову оптимальной. Модификаторы PCRE расширяют языковые возможности Regex бесчисленными способами.

Неодобрение в PHP6
Вот одна из наиболее важных причин, чтобы не использовать POSIX. Регулярные выражения POSIX и связанные с ними функции (ereg(), eregi(), ereg_replace() и eregi_replace()) больше не будет частью PHP6. Они будут доступны только в рамках расширения через PECL (что является в основном расширениями PHP, написанные непосредственно на C для оптимизации). Многие люди не смогут добавить это расширение, в особенности на общих хостах, так что нет большого смысла учиться POSIX.

Юзабилити в Perl
Регулярные выражения PCRE были смоделированы для движка регэкспов Perl (следовательно, Perl-совместимые), и зачастую могут быть перенесены непосредственно в Perl, если вы знаете, как на самом деле используют регулярные выражения Perl. Многие из сегодняшних языков, которые поддерживают регулярные выражения также используют некоторые формы PCRE, так что вам нужно всего лишь получить одну разновидность Regex, с тем чтобы использовать ее в различных языках.

Собираем все это вместе
Ну вот, теперь у нас есть основной синтаксис, и я собираюсь выложить некоторые примеры шаблонов для вас, чтобы проанализировать, а затем показать вам, что именно они делают.

/^w+:(s+w+)s+d+$/m
Совпадение слова, двоеточия, пробела, слова, пробела, и некоторых цифр на каждой строке

/pro(b|n|r|l)ate/i
Совпадение: probate, pronate, prorate, prolate, без учета регистра

/^[+-]?d+$/
Найдет целое число, которое может быть с + или - (или даже без ничего) перед ним. Он может также быть снабжен впереди нулями, поскольку 0 включен в d.

~//start
(.+?)
//end~is
Совпадет с //start, с переносом строки, любым количеством символов в любом количестве строк (модификатор //s), переносом строки, и //end

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

/(d)(d{3})(?!d)/
replacement: $1, $2
Я надеюсь, что некоторые из этих базовых шаблонов больше заинтересовали вас в продолжении изучения регулярных выражений.

Заключение и будущие статьи
Этот учебник был призван стать (всеобъемлющим) учебным пособием по основному синтаксису регулярных выражений. Есть еще много других современных концепций, но это будет темой 3 или 4 урока в этой серии. В следующем учебном пособии будут участвовать действительное применение этих шаблонов в PHP, создавая сопоставления и используя метасимволы группировки для создания совпадений с группой, подстановкой, и некоторые другие понятия, непосредственно связанные с использованием Regex в PHP. Потом, я расскажу про все продвинутые концепции, с тем чтобы помочь вам создать более эффективный и более конкретный шаблон.

Просто, чтобы показать вам полезные регулярные выражения, я на самом деле должен был использовать один для исправления некоторых тегов, которые я использовал, чтобы показать вам регулярные выражения. Он выглядел, как этот:

![code(=php)?](.+?)[/code]!is
Он находит все теги кода для меня, так что я мог бы легко использовать шаблон замены, чтобы заставить их быть нужными мне.

http://www.phparticles.ru/php/regulyarnye-vyrazheniya-chast-1-osnovy-sintaksisa-prodolzhenie.html

18.227.140.251 / 2024-12-22_20-44-44 UTC.