preg_replace — Выполняет поиск и замену по регулярному выражению


Содержание

Preg_replace — Выполняет поиск и замену по регулярному выражению

(PHP 3 >= 3.0.9, PHP 4, PHP 5)

preg_replace — Выполняет поиск и замену по регулярному выражению

Описание mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit] )

Выполняет поиск в строке subject совпадений с шаблоном pattern и заменяет их на replacement . В случае, если параметр limit указан, будет произведена замена limit вхождений шаблона; в случае, если limit опущен либо равняется -1, будут заменены все вхождения шаблона.

Replacement может содержать ссылки вида \\ n либо (начиная с PHP 4.0.4) $n , причем последний вариант предпочтительней. Каждая такая ссылка, будет заменена на подстроку, соответствующую n ‘нной заключенной в круглые скобки подмаске. n может принимать значения от 0 до 99, причем ссылка \\0 (либо $0 ) соответствует вхождению всего шаблона. Подмаски нумеруются слева направо, начиная с единицы.

При использовании замены по шаблону с использованием ссылок на подмаски может возникнуть ситуация, когда непосредственно за маской следует цифра. В таком случае нотация вида \\n приводит к ошибке: ссылка на первую подмаску, за которой следует цифра 1, запишется как \\11 , что будет интерпретировано как ссылка на одиннадцатую подмаску. Это недоразумение можно устранить, если воспользоваться конструкцией \$<1>1 , указывающей на изолированную ссылку на первую подмаску, и следующую за ней цифру 1 .

Пример 1. Использование подмасок, за которыми следует цифра

= «April 15, 2003» ;
$pattern = «/(\w+) (\d+), (\d+)/i» ;
$replacement = «\$<1>1,\$3″ ;
echo preg_replace ( $pattern , $replacement , $string );
?>

Результатом работы этого примера будет:

Если во время выполнения функции были обнаружены совпадения с шаблоном, будет возвращено измененное значение subject , в противном случае будет возвращен исходный текст subject .

Первые три параметра функции preg_replace() могут быть одномерными массивами. В случае, если массив использует ключи, при обработке массива они будут взяты в том порядке, в котором они расположены в массиве. Указание ключей в массиве для pattern и replacement не является обязательным. Если вы все же решили использовать индексы, для сопоставления шаблонов и строк, участвующих в замене, используйте функцию ksort() для каждого из массивов.

Пример 2. Использование массивов с числовыми индексами в качестве аргументов функции preg_replace()

= «The quick brown fox jumped over the lazy dog.» ;

$patterns [ 0 ] = «/quick/» ;
$patterns [ 1 ] = «/brown/» ;
$patterns [ 2 ] = «/fox/» ;

$replacements [ 2 ] = «bear» ;
$replacements [ 1 ] = «black» ;
$replacements [ 0 ] = «slow» ;

echo preg_replace ( $patterns , $replacements , $string );
?>

The bear black slow jumped over the lazy dog.

( $patterns );
ksort ( $replacements );

echo preg_replace ( $patterns , $replacements , $string );

The slow black bear jumped over the lazy dog.

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

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

Модификатор /e меняет поведение функции preg_replace() таким образом, что параметр replacement после выполнения необходимых подстановок интерпретируется как PHP-код и только после этого используется для замены. Используя данный модификатор, будьте внимательны: параметр replacement должен содержать корректный PHP-код, в противном случае в строке, содержащей вызов функции preg_replace() , возникнет ошибка синтаксиса.

Пример 3. Замена по нескольким шаблонам

= array ( «/(19|20)(\d<2>)-(\d<1,2>)-(\d<1,2>)/» ,
«/^\s*<(\w+)>\s*=/» );
$replace = array ( «\\3/\\4/\\1\\2» , «$\\1 =» );
echo preg_replace ( $patterns , $replace , » = 1999-5-27″ );
?>

Этот пример выведет:

Пример 4. Использование модификатора /e

( «/( ]*>)/e» ,
«‘\\1’.strtoupper(‘\\2’).’\\3′» ,
$html_body );
?>

Преобразует все HTML-теги к верхнему регистру

Пример 5. Конвертор HTML в текст

// $document на выходе должен содержать HTML-документ.
// Необходимо удалить все HTML-теги, секции javascript,
// пробельные символы. Также необходимо заменить некоторые
// HTML-сущности на их эквивалент.

$text = preg_replace ( $search , $replace , $document );
?>

Замечание: Параметр limit доступен в PHP 4.0.1pl2 и выше.

Регулярные выражения для новичков

Задачи и их разборы с javascript.ru; в статье использованы комиксы xkcd.

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

Если вам когда-нибудь приходилось работать с командной строкой, вы, вероятно, использовали маски имён файлов. Например, чтобы удалить все файлы в текущей директории, которые начинаются с буквы “d”, можно написать rm d* .

Регулярные выражения представляют собой похожий, но гораздо более сильный инструмент для поиска строк, проверки их на соответствие какому-либо шаблону и другой подобной работы. Англоязычное название этого инструмента — Regular Expressions или просто RegExp. Строго говоря, регулярные выражения — специальный язык для описания шаблонов строк.

Реализация этого инструмента различается в разных языках программирования, хоть и не сильно. В данной статье мы будем ориентироваться в первую очередь на реализацию Perl Compatible Regular Expressions.

Основы синтаксиса

В первую очередь стоит заметить, что любая строка сама по себе является регулярным выражением. Так, выражению Хаха , очевидно, будет соответствовать строка “Хаха” и только она. Регулярные выражения являются регистрозависимыми, поэтому строка “хаха” (с маленькой буквы) уже не будет соответствовать выражению выше.

4 октября 2020 – 1 марта 2020, Москва и онлайн, беcплатно

Однако уже здесь следует быть аккуратным — как и любой язык, регулярные выражения имеют спецсимволы, которые нужно экранировать. Вот их список: . ^ $ * + ? < >[ ] \ | ( ) . Экранирование осуществляется обычным способом — добавлением \ перед спецсимволом.

Набор символов

Предположим, мы хотим найти в тексте все междометия, обозначающие смех. Просто Хаха нам не подойдёт — ведь под него не попадут “Хехе”, “Хохо” и “Хихи”. Да и проблему с регистром первой буквы нужно как-то решить.

Здесь нам на помощь придут наборы — вместо указания конкретного символа, мы можем записать целый список, и если в исследуемой строке на указанном месте будет стоять любой из перечисленных символов, строка будет считаться подходящей. Наборы записываются в квадратных скобках — паттерну [abcd] будет соответствовать любой из символов “a”, “b”, “c” или “d”.

Внутри набора большая часть спецсимволов не нуждается в экранировании, однако использование \ перед ними не будет считаться ошибкой. По прежнему необходимо экранировать символы “\” и “^”, и, желательно, “]” (так, [][] обозначает любой из символов “]” или «[», тогда как [[]х] – исключительно последовательность “[х]”). Необычное на первый взгляд поведение регулярок с символом “]” на самом деле определяется известными правилами, но гораздо легче просто экранировать этот символ, чем их запоминать. Кроме этого, экранировать нужно символ «-», он используется для задания диапазонов (см. ниже).

Если сразу после [ записать символ ^ , то набор приобретёт обратный смысл — подходящим будет считаться любой символ кроме указанных. Так, паттерну [^xyz] соответствует любой символ, кроме, собственно, “x”, “y” или “z”.

Итак, применяя данный инструмент к нашему случаю, если мы напишем [Хх][аоие]х[аоие] , то каждая из строк “Хаха”, “хехе”, “хихи” и даже “Хохо” будут соответствовать шаблону.

Предопределённые классы символов

Для некоторых наборов, которые используются достаточно часто, существуют специальные шаблоны. Так, для описания любого пробельного символа (пробел, табуляция, перенос строки) используется \s , для цифр — \d , для символов латиницы, цифр и подчёркивания “_” — \w .

Если необходимо описать вообще любой символ, для этого используется точка — . . Если указанные классы написать с заглавной буквы ( \S , \D , \W ) то они поменяют свой смысл на противоположный — любой непробельный символ, любой символ, который не является цифрой, и любой символ кроме латиницы, цифр или подчёркивания соответственно.

Также с помощью регулярных выражений есть возможность проверить положение строки относительно остального текста. Выражение \b обозначает границу слова, \B — не границу слова, ^ — начало текста, а $ — конец. Так, по паттерну \bJava\b в строке “Java and JavaScript” найдутся первые 4 символа, а по паттерну \bJava\B — символы c 10-го по 13-й (в составе слова “JavaScript”).

Комикс про регулярные выражения с xkcd.ru

Диапазоны

У вас может возникнуть необходимость обозначить набор, в который входят буквы, например, от “б” до “ф”. Вместо того, чтобы писать [бвгдежзиклмнопрстуф] можно воспользоваться механизмом диапазонов и написать [б-ф] . Так, паттерну x[0-8A-F][0-8A-F] соответствует строка “xA6”, но не соответствует “xb9” (во-первых, из-за того, что в диапазоне указаны только заглавные буквы, во-вторых, из-за того, что 9 не входит в промежуток 0-8).

Механизм диапазонов особенно актуален для русского языка, ведь для него нет конструкции, аналогичной \w . Чтобы обозначить все буквы русского алфавита, можно использовать паттерн [а-яА-ЯёЁ] . Обратите внимание, что буква “ё” не включается в общий диапазон букв, и её нужно указывать отдельно.

Квантификаторы (указание количества повторений)

Вернёмся к нашему примеру. Что, если в “смеющемся” междометии будет больше одной гласной между буквами “х”, например “Хаахаааа”? Наша старая регулярка уже не сможет нам помочь. Здесь нам придётся воспользоваться квантификаторами.

Квантификатор Число повторений Пример Подходящие строки
Ровно n раз Ха<3>ха Хаааха
От m до n включительно Ха<2,4>ха Хаа, Хааа, Хааааха
Не менее m Ха<2,>ха Хааха, Хаааха, Хааааха и т. д.
Не более n Ха<,3>ха Хха, Хаха, Хааха, Хаааха

Обратите внимание, что квантификатор применяется только к символу, который стоит перед ним.

Некоторые часто используемые конструкции получили в языке регулярных выражений специальные обозначения:

Квантификатор Аналог Значение
? Ноль или одно вхождение
* Ноль или более
+ Одно или более

Таким образом, с помощью квантификаторов мы можем улучшить наш шаблон для междометий до [Хх][аоеи]+х[аоеи]* , и он сможет распознавать строки “Хааха”, “хееееех” и “Хихии”.

Ленивая квантификация

Предположим, перед нами стоит задача — найти все HTML-теги в строке

Очевидное решение здесь не сработает — оно найдёт всю строку целиком, т.к. она начинается с тега абзаца и им же заканчивается. То есть содержимым тега будет считаться строка

Это происходит из-за того, что по умолчанию квантификатор работают по т.н. жадному алгоритму — старается вернуть как можно более длинную строку, соответствующую условию. Решить проблему можно двумя способами. Первый — использовать выражение ]*> , которое запретит считать содержимым тега правую угловую скобку. Второй — объявить квантификатор не жадным, а ленивым. Делается это с помощью добавления справа к квантификатору символа ? . Т.е. для поиска всех тегов выражение обратится в .

Ревнивая квантификация

Иногда для увеличения скорости поиска (особенно в тех случаях, когда строка не соответствует регулярному выражению) можно использовать запрет алгоритму возвращаться к предыдущим шагам поиска для того, чтобы найти возможные соответствия для оставшейся части регулярного выражения. Это называется ревнивой квантификацией. Квантификатор делается ревнивым с помощью добавления к нему справа символа + . Ещё одно применение ревнивой квантификации — исключение нежелательных совпадений. Так, паттерну ab*+a в строке “ababa” будут соответствовать только первые три символа, но не символы с третьего по пятый, т.к. символ “a”, который стоит на третьей позиции, уже был использован для первого результата.

Скобочные группы

Для нашего шаблона “смеющегося” междометия осталась самая малость — учесть, что буква “х” может встречаться более одного раза, например, “Хахахахааахахооо”, а может и вовсе заканчиваться на букве “х”. Вероятно, здесь нужно применить квантификатор для группы [аиое]+х , но если мы просто напишем [аиое]х+ , то квантификатор + будет относиться только к символу “х”, а не ко всему выражению. Чтобы это исправить, выражение нужно взять в круглые скобки: ([аиое]х)+ .

Таким образом, наше выражение превращается в [Хх]([аиое]х?)+ — сначала идёт заглавная или строчная “х”, а потом произвольное ненулевое количество гласных, которые (возможно, но не обязательно) перемежаются одиночными строчными “х”. Однако это выражение решает проблему лишь частично — под это выражение попадут и такие строки, как, например, “хихахех” — кто-то может быть так и смеётся, но допущение весьма сомнительное. Очевидно, мы можем использовать набор из всех гласных лишь единожды, а потом должны как-то опираться на результат первого поиска. Но как?…

Запоминание результата поиска по группе (обратная связь)

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

Результат поиска по всем регулярному выражению: “

”.
Результат поиска по первой группе: “p”, “b”, “/b”, “i”, “/i”, “/i”, “/p”.

На результат поиска по группе можно ссылаться с помощью выражения \n , где n — цифра от 1 до 9. Например выражению (\w)(\w)\1\2 соответствуют строки “aaaa”, “abab”, но не соответствует “aabb”.

Если выражение берётся в скобки только для применения к ней квантификатора (не планируется запоминать результат поиска по этой группе), то сразу после первой скобки стоит добавить ?: , например (?:[abcd]+\w) .

С использованием этого механизма мы можем переписать наше выражение к виду [Хх]([аоие])х?(?:\1х?)* .

Перечисление

Чтобы проверить, удовлетворяет ли строка хотя бы одному из шаблонов, можно воспользоваться аналогом булевого оператора OR, который записывается с помощью символа | . Так, под шаблон Анна|Одиночество попадают строки “Анна” и “Одиночество” соответственно. Особенно удобно использовать перечисления внутри скобочных групп. Так, например (?:a|b|c|d) полностью эквивалентно [abcd] (в данном случае второй вариант предпочтительнее в силу производительности и читаемости).

С помощью этого оператора мы сможем добавить к нашему регулярному выражению для поиска междометий возможность распознавать смех вида “Ахахаах” — единственной усмешке, которая начинается с гласной: [Хх]([аоие])х?(?:\1х?)*|[Аа]х?(?:ах?)+

Полезные сервисы

Потренироваться и / или проверить своё регулярное выражение на каком-либо тексте без написания кода можно с помощью таких сервисов, как RegExr, Regexpal или Regex101. Последний, вдобавок, приводит краткие пояснения к тому, как регулярка работает.

Разобраться, как работает регулярное выражение, которое попало к вам в руки, можно с помощью сервиса Regexper — он умеет строить понятные диаграмы по регулярному выражению.

RegExp Builder — визуальный конструктор функций JavaScript для работы с регулярными выражениями.

Больше инструментов можно найти в нашей подборке.

Задания для закрепления

Найдите время

Время имеет формат часы:минуты. И часы, и минуты состоят из двух цифр, пример: 09:00. Напишите регулярное выражение для поиска времени в строке: “Завтрак в 09:00”. Учтите, что “37:98” – некорректное время.

Preg_replace — Выполняет поиск и замену по регулярному выражению

До сих пор здесь обсуждался язык регулярных выражений вне всякой связи с каким-либо языком программирования. Пришло время обсудить, как пользоваться возможностями регулярных выражений в программах на Perl.

Следующий фрагмент кода проверяет, содержит ли переменная $_ десятичную запись целого числа (как минимум одна десятичная цифра, которой, возможно, предшествует знак минуса):

Мы видим, что знаки косой (слэши) черты служат ограничителями, внутри которых заключён шаблон. Это, конечно, означает, что просто так эти знаки не получится использовать в шаблоне. Не нужно быть очень умным, чтобы сообразить, как обойти эту трудность. Разумеется, следует ставить бэкслэши перед слэшами. К примеру, если в переменной $_ находится полное имя файла, проверка того, лежит ли файл в директории /usr/bin , будет выглядеть так:

Если часто приходится обрабатывать имена файлов и директорий с помощью регулярных выражений, удобно использовать альтернативные формы оператора поиска с другими ограничителями: m#⋯# , m!⋯! , m+⋯+ , m(⋯) , m[⋯] . Сравните: m/^\/usr\/bin\// и m#^/usr/bin/# . Тогда, помещая в шаблон выбранный символ ограничителя (кроме скобок), нужно позаботиться о его защите и вставить перед ним бэкслэш. Со скобками в качестве ограничителей такой проблемы нет (почему?). Программисты на Perl имеют свои нежные привязанности к тому или иному виду ограничителей.

Оператор замены

Требуется заменить в переменной $_ несколько идущих подряд пробелов на один. Эта задача решается при помощи оператора s/\ +/ / .

В переменной $_ содержатся фамилия, имя и отчество человека, разделённые пробелами, например, Чайковский Пётр Ильич . Нужно заменить имя и отчество инициалами: Чайковский П. И. . Решение: s/^(\S+) (\S)\S* (\S)\S*$/$1 $2. $3./ (здесь предполагается, что фамилия, имя и отчество не содержат пробелов, что, как правило, верно, но не всегда).

Этот пример показывает, что переменные захвата вполне можно использовать во второй части оператора замены.

Если подобным образом нужно обработать все элементы массива, применим цикл:

Оператор связывания

Может сложиться впечатление, что с помощью регулярных выражений в Perl можно осуществлять поиск лишь в переменной $_ . На самом деле поиск возможен в любой скалярной переменной, в ячейке массива (обычного и ассоциативного), и вообще в произвольном скалярном значении. Нужно лишь связать переменную или значение с оператором поиска. Для этого имеется специальный оператор =

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

Оператор связывания возвращает истинное или ложное значение в зависимости от успешности поиска. У него в компании имеется дополнительный оператор !

, который, наоборот, возвращает ложное значение в случае успешного поиска, и истинное в случае неуспешного. Таким образом, выражение $a !

m/⋯/ равносильно выражению !( $a =

Встроенная процедура split

Встроенная процедура split использует шаблоны поиска. Она получает в качестве аргументов регулярное выражение и строку, а возвращает массив. В исходной строке отыскиваются все подстроки, соответствующие шаблону. Фрагменты строки, заключённые между найденными подстроками, как раз и возвращаются в массиве в порядке их появления. Если строка отсутствует в списке параметров split , используется, как обычно в таких случаях, переменная по умолчанию $_ .

Например, строку, содержащую слово во всевозможных падежах, записанных через пробел, можно превратить в массив слов следующим образом:

Если в качестве разделителей могут появиться другие пробельные символы, да ещё по нескольку подряд, шаблон следует заменить на \s+ :

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

Мы не упоминаем здесь многие другие возможности, предоставляемые процедурой split , отсылая читателя к документации на man- странице .

Популярные примеры работы регулярных выражений в PHP

Вопросов по данной теме уйма. И я решил создать свою подборку регулярных выражений. Думаю многим поможет!

Для справки.
. — (точка) соответствует любому символу.
<> — (фигурные скобки) нужны для обозначения количества необходимых символов. Например, w <3>— три буквы w подряд. Также есть диапозон z<2,5>, то есть z может повторяться от 2 до 5 раз.
| — (вертикальная черта) логическое или в регулярных выражениях.
\n — перевод строки
\r — так же перевод строки
\t — табуляция
\d — цифра
\D — только не цифра
\s — пробел
\S — только не пробел
\w — все буквы, цифры и знак подчеркивания «_»
\W — только не буква, цифра или подчеркивание
Модификаторы в конце выражения
/i — делает поиск по выражению регистронезависимым. Нет разницы между заглавным и прописным символом
/U — модификатор указывает на то, что результатом поиска должен быть самый короткий отрывок, удовлетворяющий маске поиска. Рекомендую всегда использовать данный модификатор
/m — этот модификатор позволяет искать отрезок текста только внутри одной строки
/s — поиск идёт всему тексту, не обращая внимания на переносы строк
/x — игнорируются пробельные символы, в том числе символы табуляции и перевода строки

Примеры preg_replace PHP


1. Удаляем определённую ссылку в переменной text

2. Удаляем комментарии в переменной text

3. Удаляем спецсимволы

4. Удаляем всё, что между

5. Удаляем всё, что между

6. Удаляем конкретные символы из строки

7. Удаляем пробелы по бокам строки и обычные пробелы

8. Удаляем лишние переводы строк и переносы

9. Удаляем расширения в названиях файлов

10. Создаём функцию обработки текста

11. Найти содержимое определённого тега и вставить его в другие теги

12. Удаляем многократно повторяющиеся знаки препинания (например, . или . )

13. Добавить или убрать текст в начале или конце переменной с текстом

14. Находим все http:// и заменяем на ссылки

15. Удаление GET-параметров из URL

16. Добавить тег br в начало или конец строк

17. Как конвертировать html в текст

18. Как разобрать email и сделать ссылку

Примеры preg_match PHP

1. проверка mail адреса на корректность

2. Найти mail адреса в тексте

3. Является ли переменная числом, длиной от 13 до 16 символов (проверка кредитной карты)

4. Проверка имени файла

Программы (exe, xpi, . )

Изображения (jpg, png, . )

5. Ищем в тексте мобильные телефоны РФ

6. Состоит ли строка только из букв, цифр и _, длиной от 8 до 20 символов:

7. Есть ли в строке идущие подряд символы, не менее 3-х символов подряд (типа абвгДДДеё, но не ааббаабб):

8. Поиск в разных частях строки конструкции:

9. Проверки на тип браузера. Возвращает true если browser = Netscape 2, 3 or MSIE 3.

Примеры ereg PHP

1. Проверка mail адреса в тексте

Подстановки в регулярных выражениях Substitutions in Regular Expressions

Подстановки — это языковые элементы, которые распознаются только в шаблонах замены. Substitutions are language elements that are recognized only within replacement patterns. Они используют шаблон регулярного выражения для определения всего текста или его части, предназначенной для замены совпадающего текста во входной строке. They use a regular expression pattern to define all or part of the text that is to replace matched text in the input string. Шаблон замены может включать одну или несколько подстановок вместе с литеральными символами. The replacement pattern can consist of one or more substitutions along with literal characters. Для перегруженных версий метода Regex.Replace , имеющих параметр replacement , и для метода Match.Result предоставляются шаблоны замены. Replacement patterns are provided to overloads of the Regex.Replace method that have a replacement parameter and to the Match.Result method. Эти методы заменяют совпавший шаблон шаблоном, определенным параметром replacement . The methods replace the matched pattern with the pattern that is defined by the replacement parameter.

Платформа .NET Framework определяет элементы подстановки, перечисленные в следующей таблице. The .NET Framework defines the substitution elements listed in the following table.

Подстановка Substitution ОПИСАНИЕ Description
$ число $ number Включает в строку замены последнюю подстроку, соответствующую группе записи, которая идентифицируется как number, где number — десятичное значение. Includes the last substring matched by the capturing group that is identified by number, where number is a decimal value, in the replacement string. Дополнительные сведения см. в разделе Подстановка нумерованной группы. For more information, see Substituting a Numbered Group.
$< name > $< name > Включает в строку замены последнюю подстроку, соответствующую именованной группе, обозначаемой как (? name > ) . Includes the last substring matched by the named group that is designated by (? name > ) in the replacement string. Дополнительные сведения см. в разделе Подстановка именованной группы. For more information, see Substituting a Named Group.
$$ Включает один литерал «$» в строку замены. Includes a single «$» literal in the replacement string. Дополнительные сведения см. в разделе Подстановка символа «$». For more information, see Substituting a «$» Symbol.
$& Включает копию всего соответствия в строку замены. Includes a copy of the entire match in the replacement string. Дополнительные сведения см. в разделе Подстановка всего соответствия. For more information, see Substituting the Entire Match.
$` Включает весь текст входной строки до соответствия в строку замены. Includes all the text of the input string before the match in the replacement string. Дополнительные сведения см. в разделе Подстановка текста до соответствия. For more information, see Substituting the Text before the Match.
$’ $’ Включает весь текст входной строки после соответствия в строку замены. Includes all the text of the input string after the match in the replacement string. Дополнительные сведения см. в разделе Подстановка текста после соответствия. For more information, see Substituting the Text after the Match.
$+ Включает последнюю записанную группу в строку замены. Includes the last group captured in the replacement string. Дополнительные сведения см. в разделе Подстановка последней записанной группы. For more information, see Substituting the Last Captured Group.
$ $ Включает всю входную строку в строку замены. Includes the entire input string in the replacement string. Дополнительные сведения см. в разделе Замена всей входной строки. For more information, see Substituting the Entire Input String.

Элементы подстановки и шаблонов замены Substitution Elements and Replacement Patterns

В шаблонах замены распознается только одна специальная конструкция: подстановки. Substitutions are the only special constructs recognized in a replacement pattern. Ни один из остальных элементов языка регулярных выражений, включая escape-символы и точку ( . ), которая соответствует любому знаку, не поддерживается. None of the other regular expression language elements, including character escapes and the period ( . ), which matches any character, are supported. Аналогичным образом, подставляемые элементы языка распознаются только в шаблонах замены и никогда не являются допустимыми в шаблоны регулярных выражений. Similarly, substitution language elements are recognized only in replacement patterns and are never valid in regular expression patterns.

Единственный знак, который может встречаться в шаблоне регулярного выражения либо в подстановке, — это знак $ , хотя он в разных случаях имеет разное значение. The only character that can appear either in a regular expression pattern or in a substitution is the $ character, although it has a different meaning in each context. В шаблоне регулярного выражения $ является привязкой, совпадающей с концом строки. In a regular expression pattern, $ is an anchor that matches the end of the string. В шаблоне замены $ указывает начало подстановки. In a replacement pattern, $ indicates the beginning of a substitution.

Для получения возможностей, подобных шаблону замены в регулярном выражении, используйте обратную ссылку. For functionality similar to a replacement pattern within a regular expression, use a backreference. Дополнительные сведения об обратных ссылках см. в разделе Конструкции обратных ссылок. For more information about backreferences, see Backreference Constructs.

Подстановка нумерованной группы Substituting a Numbered Group

Языковой элемент $ number включает последнюю подстроку, сопоставленную по группе записи number в строке замены, где number — это индекс группы записи. The $ number language element includes the last substring matched by the number capturing group in the replacement string, where number is the index of the capturing group. Например, шаблон замены $1 указывает, что совпадающая подстрока будет заменена первой группой записи. For example, the replacement pattern $1 indicates that the matched substring is to be replaced by the first captured group. Дополнительные сведения о нумерованных группах записи см. в разделе Grouping Constructs. For more information about numbered capturing groups, see Grouping Constructs.

Все цифры, указанные после $ , интерпретируются как относящиеся к группе number . All digits that follow $ are interpreted as belonging to the number group. Если это не соответствует вашим намерениям, можно вместо этого подставить именованную группу. If this is not your intent, you can substitute a named group instead. Например, можно использовать строку замены $<1>1 вместо $11 , чтобы определить строку замены как значение первой записанной группы вместе с номером «1». For example, you can use the replacement string $<1>1 instead of $11 to define the replacement string as the value of the first captured group along with the number «1». Дополнительные сведения см. в разделе Подстановка именованной группы. For more information, see Substituting a Named Group.

Группы записи, которым явно не назначены имена с помощью синтаксиса (? name >) , нумеруются слева направо, начиная с единицы. Capturing groups that are not explicitly assigned names using the (? name >) syntax are numbered from left to right starting at one. Именованные группы также нумеруются слева направо, начиная с номера, превышающего индекс последней неименованной группы. Named groups are also numbered from left to right, starting at one greater than the index of the last unnamed group. Например, в регулярном выражении (\w)(? \d) индекс именованной группы digit — 2. For example, in the regular expression (\w)(? \d) , the index of the digit named group is 2.

Если number не соответствует допустимой группе записи, определенной в шаблоне регулярного выражения, $ number интерпретируется как последовательность литеральных символов, используемая для замены каждого соответствия. If number does not specify a valid capturing group defined in the regular expression pattern, $ number is interpreted as a literal character sequence that is used to replace each match.

В следующем примере подстановка $ number используется для удаления символа валюты из десятичного значения. The following example uses the $ number substitution to strip the currency symbol from a decimal value. Она удаляет символы денежной единицы, найденные в начале или конце денежного значения, и распознает два наиболее распространенных десятичных разделителя («.» и «,»). It removes currency symbols found at the beginning or end of a monetary value, and recognizes the two most common decimal separators («.» and «,»).

Шаблон регулярного выражения \p*(\s?\d+[.,]?\d*)\p* определяется, как показано в следующей таблице. The regular expression pattern \p*(\s?\d+[.,]?\d*)\p* is defined as shown in the following table.

Шаблон Pattern ОПИСАНИЕ Description
\p* Совпадение с нулем или более символами денежной единицы. Match zero or more currency symbol characters.
\s? Совпадение с нулем или одним символом пробела. Match zero or one white-space characters.
\d+ Совпадение с одной или несколькими десятичными цифрами. Match one or more decimal digits.
[.,]? Совпадение с нулем или одной точкой либо запятой. Match zero or one period or comma.
\d* Соответствует нулю или нескольким десятичным числам. Match zero or more decimal digits.
(\s?\d+[.,]?\d*) Совпадение с пробелом, за которым следует одна или несколько десятичных цифр, после которых идет ноль или одна точка либо запятая, а за ними — ноль или более десятичных цифр. Match a white space followed by one or more decimal digits, followed by zero or one period or comma, followed by zero or more decimal digits. Это первая группа записи. This is the first capturing group. Так как шаблон замены имеет вид $1 , вызов метода Regex.Replace заменяет всю совпадающую подстроку данной группой записи. Because the replacement pattern is $1 , the call to the Regex.Replace method replaces the entire matched substring with this captured group.

Подстановка именованной группы Substituting a Named Group

Языковой элемент $< name > замещает последнюю подстроку, сопоставленную по группе записи name , где name — это имя группы записи, определенной в языковом элементе (? name >) . The $< name > language element substitutes the last substring matched by the name capturing group, where name is the name of a capturing group defined by the (? name >) language element. Дополнительные сведения об именованных группах записи см. в разделе Grouping Constructs. For more information about named capturing groups, see Grouping Constructs.

Если name не соответствует допустимой именованной группе записи, определенной в регулярном выражении, и состоит из цифр, то $< name > интерпретируется как нумерованная группа. If name doesn’t specify a valid named capturing group defined in the regular expression pattern but consists of digits, $< name > is interpreted as a numbered group.

Если name не соответствует ни допустимой именованной группе записи, ни допустимой нумерованной группе записи, определенной в шаблоне регулярного выражения, $< name > интерпретируется как последовательность литеральных символов, используемая для замены каждого соответствия. If name specifies neither a valid named capturing group nor a valid numbered capturing group defined in the regular expression pattern, $< name > is interpreted as a literal character sequence that is used to replace each match.

В следующем примере подстановка $< name > используется для удаления символа валюты из десятичного значения. The following example uses the $< name > substitution to strip the currency symbol from a decimal value. Она удаляет символы денежной единицы, найденные в начале или конце денежного значения, и распознает два наиболее распространенных десятичных разделителя («.» и «,»). It removes currency symbols found at the beginning or end of a monetary value, and recognizes the two most common decimal separators («.» and «,»).

Шаблон Pattern ОПИСАНИЕ Description
\p* Совпадение с нулем или более символами денежной единицы. Match zero or more currency symbol characters.
\s? Совпадение с нулем или одним символом пробела. Match zero or one white-space characters.
\d+ Совпадение с одной или несколькими десятичными цифрами. Match one or more decimal digits.
[.,]? Совпадение с нулем или одной точкой либо запятой. Match zero or one period or comma.
\d* Соответствует нулю или нескольким десятичным числам. Match zero or more decimal digits.
(?\s?\d[.,]?\d*) Совпадение с пробелом, за которым следует одна или несколько десятичных цифр, после которых идет ноль или одна точка либо запятая, а за ними — ноль или более десятичных цифр. Match a white space, followed by one or more decimal digits, followed by zero or one period or comma, followed by zero or more decimal digits. Это группа записи с именем amount . This is the capturing group named amount . Так как шаблон замены имеет вид $ , вызов метода Regex.Replace заменяет всю совпадающую подстроку данной группой записи. Because the replacement pattern is $ , the call to the Regex.Replace method replaces the entire matched substring with this captured group.

Подстановка знака «$» Substituting a «$» Character

Подстановка $$ вставляет символ литерала «$»в строку замены. The $$ substitution inserts a literal «$» character in the replaced string.

В следующем примере объект NumberFormatInfo используется для определения символа валюты для текущего языка и региональных параметров и его размещения в строке валюты. The following example uses the NumberFormatInfo object to determine the current culture’s currency symbol and its placement in a currency string. Затем он динамически создает как шаблон регулярного выражения, так и шаблон замены. It then builds both a regular expression pattern and a replacement pattern dynamically. Если пример выполняется на компьютере, где в качестве языка и региональных параметров задано значение «Английский — США» (en-US), будет создан шаблон регулярного выражения \b(\d+)(\.(\d+))? и шаблон замены $$ $1$2 . If the example is run on a computer whose current culture is en-US, it generates the regular expression pattern \b(\d+)(\.(\d+))? and the replacement pattern $$ $1$2 . Шаблон замены замещает совпавший текст символом валюты и пробелом после первой и второй записанной группы. The replacement pattern replaces the matched text with a currency symbol and a space followed by the first and second captured groups.

Шаблон регулярного выражения \b(\d+)(\.(\d+))? определяется, как показано в следующей таблице. The regular expression pattern \b(\d+)(\.(\d+))? is defined as shown in the following table.

Шаблон Pattern ОПИСАНИЕ Description
\b Начало соответствия в начале границы слова. Start the match at the beginning of a word boundary.
(\d+) Совпадение с одной или несколькими десятичными цифрами. Match one or more decimal digits. Это первая группа записи. This is the first capturing group.
\. Совпадение с точкой (десятичным разделителем). Match a period (the decimal separator).
(\d+) Совпадение с одной или несколькими десятичными цифрами. Match one or more decimal digits. Это третья группа записи. This is the third capturing group.
(\.(\d+))? Совпадение с нулем или одним вхождением точки, за которой следует одна или несколько десятичных цифр. Match zero or one occurrence of a period followed by one or more decimal digits. Это вторая группа записи. This is the second capturing group.

Подстановка всего соответствия Substituting the Entire Match

Подстановка $& включает все соответствие в строку замены. The $& substitution includes the entire match in the replacement string. Часто она используется для добавления подстроки в начало или в конец совпадающей строки. Often, it is used to add a substring to the beginning or end of the matched string. Например, шаблон замены ($&) добавляет скобки в начало и в конец каждого соответствия. For example, the ($&) replacement pattern adds parentheses to the beginning and end of each match. Если нет соответствия, подстановка $& не оказывает влияния. If there is no match, the $& substitution has no effect.

В следующем примере используется подстановка $& для добавления кавычек в начало и в конец названий книг, хранящихся в строковом массиве. The following example uses the $& substitution to add quotation marks at the beginning and end of book titles stored in a string array.

Шаблон регулярного выражения ^(\w+\s?)+$ определяется, как показано в следующей таблице. The regular expression pattern ^(\w+\s?)+$ is defined as shown in the following table.

Шаблон Pattern ОПИСАНИЕ Description
^ Начало соответствия в начале входной строки. Start the match at the beginning of the input string.
(\w+\s?)+ Выделяет один или несколько раз шаблон из одного или нескольких словообразующих символов, за которыми следует ноль или один символ пробела. Match the pattern of one or more word characters followed by zero or one white-space characters one or more times.
$ Соответствует концу входной строки. Match the end of the input string.

Шаблон замены «$&» добавляет литеральные кавычки в начало и в конец каждого соответствия. The «$&» replacement pattern adds a literal quotation mark to the beginning and end of each match.

Подстановка текста до соответствия Substituting the Text Before the Match

Подстановка $` заменяет совпадающую строку всей входной строкой до соответствия. The $` substitution replaces the matched string with the entire input string before the match. То есть она дублирует входную строку вплоть до соответствия, удаляя совпадающий текст. That is, it duplicates the input string up to the match while removing the matched text. Любой текст, следующий за совпадающим текстом, не изменяется в результирующей строке. Any text that follows the matched text is unchanged in the result string. Если во входной строке несколько соответствий, текст замены выводится из исходной входной строки, а не из строки, в которой текст был заменен более ранними совпадениями. If there are multiple matches in an input string, the replacement text is derived from the original input string, rather than from the string in which text has been replaced by earlier matches. (Иллюстрация приведена в примере.) Если нет соответствия, подстановка $` не оказывает влияния. (The example provides an illustration.) If there is no match, the $` substitution has no effect.

В следующем примере шаблон регулярного выражения \d+ используется для сопоставления последовательности из одной или нескольких цифр десятичного числа во входной строке. The following example uses the regular expression pattern \d+ to match a sequence of one or more decimal digits in the input string. Строка замены $` заменяет эти цифры текстом, который предшествует совпадению. The replacement string $` replaces these digits with the text that precedes the match.

В этом примере входная строка «aa1bb2cc3dd4ee5» содержит пять совпадений. In this example, the input string «aa1bb2cc3dd4ee5» contains five matches. В следующей таблице показано, как подстановка $` вызывает замену обработчиком регулярных выражений каждого соответствия во входной строке. The following table illustrates how the $` substitution causes the regular expression engine to replace each match in the input string. Вставленный текст отображается в столбце результатов полужирным шрифтом. Inserted text is shown in bold in the results column.

Соответствие Match Положение Position Строка до соответствия String before match Результирующая строка Result string
1 1 2 2 aa aa aaaabb2cc3dd4ee5 aaaabb2cc3dd4ee5
2 2 5 5 aa1bb aa1bb aaaabbaa1bbcc3dd4ee5 aaaabbaa1bbcc3dd4ee5
3 3 8 8 aa1bb2cc aa1bb2cc aaaabbaa1bbccaa1bb2ccdd4ee5 aaaabbaa1bbccaa1bb2ccdd4ee5
4 4 11 11 aa1bb2cc3dd aa1bb2cc3dd aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddee5 aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddee5
5 5 14 14 aa1bb2cc3dd4ee aa1bb2cc3dd4ee aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddeeaa1bb2cc3dd4ee aaaabbaa1bbccaa1bb2ccddaa1bb2cc3ddeeaa1bb2cc3dd4ee

Подстановка текста после соответствия Substituting the Text After the Match

Подстановка $’ заменяет совпадающую строку всей входной строкой после соответствия. The $’ substitution replaces the matched string with the entire input string after the match. То есть входная строка после соответствия дублируется с удалением совпадающего текста. That is, it duplicates the input string after the match while removing the matched text. Любой текст, который предшествует совпадающему тексту, не изменяется в результирующей строке. Any text that precedes the matched text is unchanged in the result string. Если нет соответствия, подстановка $’ не оказывает влияния. If there is no match, the $’ substitution has no effect.

В следующем примере шаблон регулярного выражения \d+ используется для сопоставления последовательности из одной или нескольких цифр десятичного числа во входной строке. The following example uses the regular expression pattern \d+ to match a sequence of one or more decimal digits in the input string. Строка замены $’ заменяет эти цифры текстом, который следует за соответствием. The replacement string $’ replaces these digits with the text that follows the match.

В этом примере входная строка «aa1bb2cc3dd4ee5» содержит пять совпадений. In this example, the input string «aa1bb2cc3dd4ee5» contains five matches. В следующей таблице показано, как подстановка $’ вызывает замену обработчиком регулярных выражений каждого соответствия во входной строке. The following table illustrates how the $’ substitution causes the regular expression engine to replace each match in the input string. Вставленный текст отображается в столбце результатов полужирным шрифтом. Inserted text is shown in bold in the results column.

Соответствие Match Положение Position Строка после соответствия String after match Результирующая строка Result string
1 1 2 2 bb2cc3dd4ee5 bb2cc3dd4ee5 aabb2cc3dd4ee5bb2cc3dd4ee5 aabb2cc3dd4ee5bb2cc3dd4ee5
2 2 5 5 cc3dd4ee5 cc3dd4ee5 aabb2cc3dd4ee5bbcc3dd4ee5cc3dd4ee5 aabb2cc3dd4ee5bbcc3dd4ee5cc3dd4ee5
3 3 8 8 dd4ee5 dd4ee5 aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5dd4ee5 aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5dd4ee5
4 4 11 11 ee5 ee5 aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee5 aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee5
5 5 14 14 String.Empty aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee aabb2cc3dd4ee5bbcc3dd4ee5ccdd4ee5ddee5ee

Подстановка последней записанной группы Substituting the Last Captured Group

Подстановка $+ заменяет совпадающую строку всей последней группой записи. The $+ substitution replaces the matched string with the last captured group. Если группы записи отсутствуют или значение последней захваченной группы равно String.Empty, подстановка $+ не оказывает влияния. If there are no captured groups or if the value of the last captured group is String.Empty, the $+ substitution has no effect.

В следующем примере в строке определяются повторяющиеся слова и используется подстановка $+ для их замены одним вхождением слова. The following example identifies duplicate words in a string and uses the $+ substitution to replace them with a single occurrence of the word. Параметр RegexOptions.IgnoreCase позволяет убедиться, что слова, отличающиеся регистром, но идентичные во всем остальном, считаются дубликатами. The RegexOptions.IgnoreCase option is used to ensure that words that differ in case but that are otherwise identical are considered duplicates.

Шаблон регулярного выражения \b(\w+)\s\1\b определяется, как показано в следующей таблице. The regular expression pattern \b(\w+)\s\1\b is defined as shown in the following table.

Шаблон Pattern ОПИСАНИЕ Description
\b Совпадение должно начинаться на границе слова. Begin the match at a word boundary.
(\w+) Совпадение с одним или несколькими символами слова. Match one or more word characters. Это первая группа записи. This is the first capturing group.
\s Соответствует пробелу. Match a white-space character.
\1 Соответствует первой группе записи. Match the first captured group.
\b Совпадение должно заканчиваться на границе слова. End the match at a word boundary.

Замена всей входной строки Substituting the Entire Input String

Подстановка $_ заменяет совпадающую строку всей входной строкой. The $_ substitution replaces the matched string with the entire input string. То есть совпадающий текст удаляется и заменяется всей строкой, включая совпадающий текст. That is, it removes the matched text and replaces it with the entire string, including the matched text.

В следующем примере сопоставляется одна или несколько цифр десятичного числа во входной строке. The following example matches one or more decimal digits in the input string. При этом используется подстановка $_ для их замены входной строкой. It uses the $_ substitution to replace them with the entire input string.

В этом примере входная строка «ABC123DEF456» содержит два совпадения. In this example, the input string «ABC123DEF456» contains two matches. В следующей таблице показано, как подстановка $_ вызывает замену обработчиком регулярных выражений каждого соответствия во входной строке. The following table illustrates how the $_ substitution causes the regular expression engine to replace each match in the input string. Вставленный текст отображается в столбце результатов полужирным шрифтом. Inserted text is shown in bold in the results column.

Форум

Справочник

Поиск по форуму
Расширенный поиск
К странице.

Регулярные выражения

Регулярные выражения в javascript имеют особую краткую форму и стандартный PCRE-синтаксис.

Работают они через специальный объект RegExp.

Кроме того, у строк есть свои методы search,match,replace, но чтобы их понять — разберем-таки сначала RegExp .

Объект RegExp

Объект типа RegExp , или, короче, регулярное выражение, можно создать двумя путями

pattern — регулярное выражение для поиска (о замене — позже), а флаги — строка из любой комбинации символов g (глобальный поиск), i (регистр неважен) и m (многострочный поиск).

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

При втором вызове — т.к регулярное выражение в кавычках, то нужно дублировать \

При поиске можно использовать большинство возможностей современного PCRE-синтаксиса.

Спецсимволы в регулярном выражении

Символ Значение
\ Для обычных символов — делает их специальными. Например, выражение /s/ ищет просто символ ‘s’. А если поставить \ перед s, то /\s/ уже обозначает пробельный символ.И наоборот, если символ специальный, например *, то \ сделает его просто обычным символом «звездочка». Например, /a*/ ищет 0 или больше подряд идущих символов ‘a’. Чтобы найти а со звездочкой ‘a*’ — поставим \ перед спец. символом: /a\*/ .
^ Обозначает начало входных данных. Если установлен флаг многострочного поиска («m») , то также сработает при начале новой строки.Например, /^A/ не найдет ‘A’ в «an A», но найдет первое ‘A’ в «An A.»
$ Обозначает конец входных данных. Если установлен флаг многострочного поиска, то также сработает в конце строки.Например, /t$/ не найдет ‘t’ в «eater», но найдет — в «eat».
* Обозначает повторение 0 или более раз. Например, /bo*/ найдет ‘boooo’ в «A ghost booooed» и ‘b’ в «A bird warbled», но ничего не найдет в «A goat grunted».
+ Обозначает повторение 1 или более раз. Эквивалентно <1,>. Например, /a+/ найдет ‘a’ в «candy» и все ‘a’ в «caaaaaaandy».
? Обозначает, что элемент может как присутствовать, так и отсутствовать. Например, /e?le?/ найдет ‘el’ в «angel» и ‘le’ в «angle.»Если используется сразу после одного из квантификаторов * , + , ? , или <> , то задает «нежадный» поиск (повторение минимально возможное количество раз, до ближайшего следующего элемента паттерна), в противоположность «жадному» режиму по умолчанию, при котором количество повторений максимально, даже если следующий элемент паттерна тоже подходит.Кроме того, ? используется в предпросмотре, который описан в таблице под (?=) , (?!) , и (?: ) .
. (Десятичная точка) обозначает любой символ, кроме перевода строки: \n \r \u2028 or \u2029. ( можно использовать [\s\S] для поиска любого символа, включая переводы строк). Например, /.n/ найдет ‘an’ и ‘on’ в «nay, an apple is on the tree», но не ‘nay’.
( x ) Находит x и запоминает. Это называется «запоминающие скобки». Например, /(foo)/ найдет и запомнит ‘foo’ в «foo bar.» Найденная подстрока хранится в массиве-результате поиска или в предопределенных свойствах объекта RegExp: $1, . $9 .Кроме того, скобки объединяют то, что в них находится, в единый элемент паттерна. Например, (abc)* — повторение abc 0 и более раз.
(?: x ) Находит x , но не запоминает найденное. Это называется «незапоминающие скобки». Найденная подстрока не сохраняется в массиве результатов и свойствах RegExp.Как и все скобки, объединяют находящееся в них в единый подпаттерн.
x (?= y ) Находит x , только если за x следует y . Например, /Jack(?=Sprat)/ найдет ‘Jack’, только если за ним следует ‘Sprat’. /Jack(?=Sprat|Frost)/ найдет ‘Jack’, только если за ним следует ‘Sprat’ или ‘Frost’. Однако, ни ‘Sprat’ ни ‘Frost’ не войдут в результат поиска.
x (?! y ) Находит x , только если за x не следует y . Например, /\d+(?!\.)/ найдет число, только если за ним не следует десятичная точка. /\d+(?!\.)/.exec(«3.141») найдет 141, но не 3.141.
x | y Находит x или y . Например, /green|red/ найдет ‘green’ в «green apple» и ‘red’ в «red apple.»
Где n — положительное целое число. Находит ровно n повторений предшествующего элемента. Например, /a<2>/ не найдет ‘a’ в «candy,» но найдет оба a в «caandy,» и первые два a в «caaandy.»
Где n — положительное целое число. Находит n и более повторений элемента. Например, /a <2,>не найдет ‘a’ в «candy», но найдет все ‘a’ в «caandy» и в «caaaaaaandy.»
Где n и m — положительные целые числа. Находят от n до m повторений элемента.
[ xyz ] Набор символов. Находит любой из перечисленных символов. Вы можете указать промежуток, используя тире. Например, [abcd] — то же самое, что [a-d] . Найдет ‘b’ в «brisket», а также ‘a’ и ‘c’ в «ache».
[^ xyz ] Любой символ, кроме указанных в наборе. Вы также можете указать промежуток. Например, [^abc] — то же самое, что [^a-c] . Найдет ‘r’ в «brisket» и ‘h’ в «chop.»
[\b] Находит символ backspace. (Не путать с \b .)
\b Находит границу слов (латинских), например пробел. (Не путать с [\b] ). Например, /\bn\w/ найдет ‘no’ в «noonday»; /\wy\b/ найдет ‘ly’ в «possibly yesterday.»
\B Обозначает не границу слов. Например, /\w\Bn/ найдет ‘on’ в «noonday», а /y\B\w/ найдет ‘ye’ в «possibly yesterday.»
\c X Где X — буква от A до Z. Обозначает контрольный символ в строке. Например, /\cM/ обозначает символ Ctrl-M.
\d находит цифру из любого алфавита (у нас же юникод). Испльзуйте [0-9], чтобы найти только обычные цифры. Например, /\d/ или /[0-9]/ найдет ‘2’ в «B2 is the suite number.»
\D Найдет нецифровой символ (все алфавиты). [^0-9] — эквивалент для обычных цифр. Например, /\D/ или /[^0-9]/ найдет ‘B’ в «B2 is the suite number.»
\f,\r,\n Соответствующие спецсимволы form-feed, line-feed, перевод строки.
\s Найдет любой пробельный символ, включая пробел, табуляцию, переводы строки и другие юникодные пробельные символы. Например, /\s\w*/ найдет ‘ bar’ в «foo bar.»
\S Найдет любой символ, кроме пробельного. Например, /\S\w*/ найдет ‘foo’ в «foo bar.»
\t Символ табуляции.
\v Символ вертикальной табуляции.
\w Найдет любой словесный (латинский алфавит) символ, включая буквы, цифры и знак подчеркивания. Эквивалентно [A-Za-z0-9_] . Например, /\w/ найдет ‘a’ в «apple,» ‘5’ в «$5.28,» и ‘3’ в «3D.»
\W Найдет любой не-(лат.)словесный символ. Эквивалентно [^A-Za-z0-9_] . Например, /\W/ и /[^$A-Za-z0-9_]/ одинаково найдут ‘%’ в «50%.»
\ n где n — целое число. Обратная ссылка на n-ю запомненную скобками подстроку. Например, /apple(,)\sorange\1/ найдет ‘apple, orange,’ в «apple, orange, cherry, peach.». За таблицей есть более полный пример.
\0 Найдет символ NUL. Не добавляйте в конец другие цифры.
\x hh Найдет символ с кодом hh (2 шестнадцатиричных цифры)
\u hhhh Найдет символ с кодом hhhh (4 шестнадцатиричных цифры).

Проверка результатов: метод test

Чтобы просто проверить, подходит ли строка под регулярное выражение, используется метод test :

Метод test начинает поиск, начиная со свойства lastIndex объекта RegExp , если оно установлено.

Поиск совпадений: метод exec

Метод exec возвращает массив и ставит свойства регулярного выражения.
Если совпадений нет, то возвращается null.

В результате выполнения скрипта будут такие результаты:

Объект Свойство/Индекс Описания Пример
myArray Содержимое myArray . [«dbBd», «bB», «d»]
index Индекс совпадения (от 0) 1
input Исходная строка. cdbBdbsbz
[0] Последние совпавшие символы dbBd
[1], . [ n ] Совпадения во вложенных скобках, если есть. Число вложенных скобок не ограничено. [1] = bB
[2] = d
myRe lastIndex Индекс, с которого начинать следующий поиск. 5
ignoreCase Показывает, что был включен регистронезависимый поиск, флаг » i «. true
global Показывает, что был включен флаг » g » поиска всех совпадений. true
multiline Показывает, был ли включен флаг многострочного поиска » m «. false
source Текст паттерна. d(b+)(d)

Если в регулярном выражении включен флаг » g «, Вы можете вызывать метод exec много раз для поиска последовательных совпадений в той же строке. Когда Вы это делаете, поиск начинается на подстроке str , с индекса lastIndex . Например, вот такой скрипт:

Этот скрипт выведет следующий текст:

В следующем примере функция выполняет поиск по input. Затем делается цикл по массиву, чтобы посмотреть, есть ли другие имена.

Предполагается, что все зарегистрированные имена находятся в массиве А:

Строковые методы, поиск и замена

Следующие методы работают с регулярными выражениями из строк.

Все методы, кроме replace, можно вызывать как с объектами типа regexp в аргументах, так и со строками, которые автоматом преобразуются в объекты RegExp.

Так что вызовы эквивалентны:

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

Метод search(regexp)

Возвращает индекс регулярного выражения в строке, или -1.


Если Вы хотите знать, подходит ли строка под регулярное выражение, используйте метод search (аналогично RegExp-методы test ). Чтобы получить больше информации, используйте более медленный метод match (аналогичный методу RegExp exec ).

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

Метод match(regexp)

Если в regexp нет флага g , то возвращает тот же результат, что regexp.exec(string) .

Если в regexp есть флаг g , то возвращает массив со всеми совпадениями.

Чтобы просто узнать, подходит ли строка под регулярное выражение regexp , используйте regexp.test(string) .

Если Вы хотите получить первый результат — попробуйте r egexp.exec(string) .

В следующем примере match используется, чтобы найти «Chapter», за которой следует 1 или более цифр, а затем цифры, разделенные точкой. В регулярном выражении есть флаг i , так что регистр будет игнорироваться.

Скрипт выдаст массив из совпадений:

  • Chapter 3.4.5.1 — полностью совпавшая строка
  • 3.4.5.1 — первая скобка
  • .1 — внутренняя скобка

Следующий пример демонстрирует использование флагов глобального и регистронезависимого поиска с match . Будут найдены все буквы от А до Е и от а до е, каждая — в отдельном элементе массива.

Замена, replace

Метод replace может заменять вхождения регулярного выражения не только на строку, но и на результат выполнения функции. Его полный синтаксис — такой:

regexp Объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2 substr Строка, которая будет заменена на newSubStr . newSubStr Строка, которая заменяет подстроку из аргумента номер 1. function Функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).

Метод replace не меняет строку, на которой вызван, а просто возвращает новую, измененную строку.

Чтобы осуществить глобальную замену, включите в регулярное выражение флаг «g» .

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

Вызов replace оставил строку без изменения, т.к искал не регулярное выражение \s , а строку «\s».

Спецсимволы в строке замены

В строке замены могут быть такие спецсимволы:

Pattern Inserts
$$ Вставляет «$».
$& Вставляет найденную подстроку.
$` Вставляет часть строки, которая предшествует найденному вхождению.
$’ Вставляет часть строки, которая идет после найденного вхождения.
$ n or $ nn Где n или nn — десятичные цифры, вставляет подстроку вхождения, запомненную n -й вложенной скобкой, если первый аргумент — объект RegExp.

Замена через функцию

Если Вы указываете вторым параметром функцию, то она выполняется при каждом совпадении.

В функции можно динамически генерировать и возвращать строку подстановки.

Первый параметр функции — найденная подстрока. Если первым аргументом replace является объект RegExp , то следующие n параметров содержат совпадения из вложенных скобок. Последние два параметра — позиция в строке, на которой произошло совпадение и сама строка.

Например, следующий вызов replace возвратит XXzzzz — XX , zzzz.

Как видите, тут две скобки в регулярном выражении, и потому в функции два параметра p1 , p2 .
Если бы были три скобки, то в функцию пришлось бы добавить параметр p3 .

Следующая функция заменяет слова типа borderTop на border-top :

Статичные регэкспы

В некоторых реализациях javascript регэкспы, заданные коротким синтаксисом /. / — статичны. То есть, такой объект создается один раз в некоторых реализациях JS, например в Firefox. В Chrome все ок.

По стандарту эта возможность разрешена ES3, но запрещена ES5.

Из-за того, что lastIndex при глобальном поиске меняется, а сам объект регэкспа статичен, первый поиск увеличивает lastIndex , а последующие — продолжают искать со старого lastIndex , т.е. могут возвращать не все результаты.

При поиске всех совпадений в цикле проблем не возникает, т.к. последняя итерация (неудачная) обнуляет lastIndex .

Дополнительно

Для общего понимания регулярных выражений можно почитать Статью в wikipedia.

Более подробно они описаны в книге (англ.) Beginning Regular Expressions.

Примеры функции замены preg_replace в PHP

С помощью функции preg_replace можно находить и изменять требуемые данные на странице.

Также читайте статью, где функцией preg_replace мы удаляем данные в профиле пользователя WordPress.

Есть схожая функция, которая вместо замены находит данные для последующей обработки, называется preg_match.

Первый параметр, с помощью регулярных выражений задаёт критерий поиска.

Второй параметр указывает на что меняем найденные данные.

Третий параметр — там где мы производим поиск.

preg_replace в DIV

Удаление содержимого внутри тега DIV:

Удаление содержимого вместе с самим тегом div:

Удаление содержимого в конкретном див теге (с конкретным классом):

Удаление всего конкретного div тега:

Удаляем изображение из контента:

preg_replace для цифр и знаков

Удаляем всё постороннее кроме цифр:

Удаление доллара спереди:

Удаление запятой из слов и цифр:

Удаление пробелов внутри цифры:

Иногда похожие задачи выполняют другие php функции:

Удаление пробелов с обоих сторон от цифр:

Удаление всех пробелов сначала и с конца выражения:

preg_replace

(PHP 4, PHP 5, PHP 7)

preg_replace — Выполняет поиск и замену по регулярному выражению

Описание

Выполняет поиск совпадений в строке subject с шаблоном pattern и заменяет их на replacement .

Список параметров

Искомый шаблон. Может быть как строкой, так и массивом строк.

Также доступны некоторые модификаторы PCRE.

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

replacement может содержать ссылки вида \\ n , либо $ n , причем последний вариант предпочтительней. Каждая такая ссылка будет заменена на подстроку, соответствующую n -ой подмаске. n может принимать значения от 0 до 99, причем ссылка \\0 (либо $0) соответствует вхождению всего шаблона. Подмаски нумеруются слева направо, начиная с единицы. Для использования обратного слеша, его необходимо продублировать (строка PHP «\\\\»).

При замене по шаблону с использованием ссылок на подмаски может возникнуть ситуация, когда непосредственно за маской следует цифра (например, установка цифры сразу после совпавшей маски). В таком случае нельзя использовать знакомую нотацию вида \\1 для ссылки на подмаски. Запись, например, \\11, смутит preg_replace() , так как она не сможет понять, хотите ли вы использовать ссылку \\1, за которой следует цифра 1 или же вы хотите просто использовать ссылку \\11, за которой ничего не следует. Это недоразумение можно устранить, если воспользоваться конструкцией $<1>1, использующей изолированную ссылку $1, и следующую за ней цифру 1.

При использовании устаревшего модификатора e эта функция экранирует некоторые символы (а именно , «, \ и NULL) в строках, замещающих обратные ссылки. Это сделано для удостоверения корректности синтаксиса при использовании обратных ссылок внутри одинарных или двойных кавычек (например, ‘strlen(\’$1\’)+strlen(«$2»)’). Убедитесь, что вы владеете синтаксисом обработки строк PHP для того, чтобы точно осознавать, как будет выглядеть интерпретированная строка.

Строка или массив строк для поиска и замены.

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

Максимально возможное количество замен каждого шаблона для каждой строки subject . По умолчанию равно -1 (без ограничений).

Если указана, то эта переменная будет заполнена количеством произведенных замен.

Возвращаемые значения

preg_replace() возвращает массив, если параметр subject является массивом, иначе возвращается строка.

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

Ошибки

С версии PHP 5.5.0, если передается модификатор «\e», вызывается ошибка уровня E_DEPRECATED . С версии PHP 7.0.0 использование модификатора «\e» является ошибкой; в этом случае выдается E_WARNING ; .

Список изменений

Версия Описание
7.0.0 Удалена поддержка модификатора /e. Вместо него используйте preg_replace_callback() .
5.5.0 Модификатор /e теперь считается устаревшим. Используйте функцию preg_replace_callback() . Смотрите документацию PREG_REPLACE_EVAL с дополнительной информацией и описанием проблем с безопасностью.
5.1.0 Добавлен параметр count

Примеры

Пример #1 Использование подмасок, за которыми следует цифра

Результат выполнения данного примера:

Пример #2 Использование массивов с числовыми индексами в качестве аргументов функции preg_replace()

Результат выполнения данного примера:

Отсортировав по ключам шаблоны и замены, получаем желаемый результат:

Результат выполнения данного примера:

Пример #3 Замена по нескольким шаблонам

Результат выполнения данного примера:

Пример #4 Чистка пробелов

Этот пример вычищает лишние пробелы в строке.

Пример #5 Использование параметра count

echo preg_replace (array( ‘/\d/’ , ‘/\s/’ ), ‘*’ , ‘xp 4 to’ , — 1 , $count );
echo $count ; //3
?>

Результат выполнения данного примера:

Примечания

При использовании массивов в pattern и replacement , ключи обрабатываются в том порядке, в котором они находятся в массиве. Этот порядок не всегда совпадает с числовым порядком индексов. Если вы используете индексы для сопоставления друг с другом нужного pattern и replacement , то вам необходимо прогнать через функцию ksort() оба массива перед использованием preg_replace() .

Смотрите также

  • Регулярные выражения PCRE
  • preg_quote() — Экранирует символы в регулярных выражениях
  • preg_filter() — Производит поиск и замену по регулярному выражению
  • preg_match() — Выполняет проверку на соответствие регулярному выражению
  • preg_replace_callback() — Выполняет поиск по регулярному выражению и замену с использованием callback-функции
  • preg_split() — Разбивает строку по регулярному выражению
  • preg_last_error() — Возвращает код ошибки выполнения последнего регулярного выражения PCRE

User Contributed Notes 48 notes

Because i search a lot 4 this:

The following should be escaped if you are trying to match that character

Special Character Definitions
\ Quote the next metacharacter
^ Match the beginning of the line
. Match any character (except newline)
$ Match the end of the line (or before newline at the end)
| Alternation
() Grouping
[] Character class
* Match 0 or more times
+ Match 1 or more times
? Match 1 or 0 times
Match exactly n times
Match at least n times
Match at least n but not more than m times
More Special Character Stuff
\t tab (HT, TAB)
\n newline (LF, NL)
\r return (CR)
\f form feed (FF)
\a alarm (bell) (BEL)
\e escape (think troff) (ESC)
\033 octal char (think of a PDP-11)
\x1B hex char
\c[ control char
\l lowercase next char (think vi)
\u uppercase next char (think vi)
\L lowercase till \E (think vi)
\U uppercase till \E (think vi)
\E end case modification (think vi)
\Q quote (disable) pattern metacharacters till \E
Even More Special Characters
\w Match a «word» character (alphanumeric plus «_»)
\W Match a non-word character
\s Match a whitespace character
\S Match a non-whitespace character
\d Match a digit character
\D Match a non-digit character
\b Match a word boundary
\B Match a non-(word boundary)
\A Match only at beginning of string
\Z Match only at end of string, or before newline at the end
\z Match only at end of string
\G Match only where previous m//g left off (works only with /g)

Post slug generator, for creating clean urls from titles.
It works with many languages.

function remove_accent ( $str )
<
$a = array( ‘À’ , ‘Á’ , ‘Â’ , ‘Ã’ , ‘Ä’ , ‘Å’ , ‘Æ’ , ‘Ç’ , ‘È’ , ‘É’ , ‘Ê’ , ‘Ë’ , ‘Ì’ , ‘Í’ , ‘Î’ , ‘Ï’ , ‘Ð’ , ‘Ñ’ , ‘Ò’ , ‘Ó’ , ‘Ô’ , ‘Õ’ , ‘Ö’ , ‘Ø’ , ‘Ù’ , ‘Ú’ , ‘Û’ , ‘Ü’ , ‘Ý’ , ‘ß’ , ‘à’ , ‘á’ , ‘â’ , ‘ã’ , ‘ä’ , ‘å’ , ‘æ’ , ‘ç’ , ‘è’ , ‘é’ , ‘ê’ , ‘ë’ , ‘ì’ , ‘í’ , ‘î’ , ‘ï’ , ‘ñ’ , ‘ò’ , ‘ó’ , ‘ô’ , ‘õ’ , ‘ö’ , ‘ø’ , ‘ù’ , ‘ú’ , ‘û’ , ‘ü’ , ‘ý’ , ‘ÿ’ , ‘Ā’ , ‘ā’ , ‘Ă’ , ‘ă’ , ‘Ą’ , ‘ą’ , ‘Ć’ , ‘ć’ , ‘Ĉ’ , ‘ĉ’ , ‘Ċ’ , ‘ċ’ , ‘Č’ , ‘č’ , ‘Ď’ , ‘ď’ , ‘Đ’ , ‘đ’ , ‘Ē’ , ‘ē’ , ‘Ĕ’ , ‘ĕ’ , ‘Ė’ , ‘ė’ , ‘Ę’ , ‘ę’ , ‘Ě’ , ‘ě’ , ‘Ĝ’ , ‘ĝ’ , ‘Ğ’ , ‘ğ’ , ‘Ġ’ , ‘ġ’ , ‘Ģ’ , ‘ģ’ , ‘Ĥ’ , ‘ĥ’ , ‘Ħ’ , ‘ħ’ , ‘Ĩ’ , ‘ĩ’ , ‘Ī’ , ‘ī’ , ‘Ĭ’ , ‘ĭ’ , ‘Į’ , ‘į’ , ‘İ’ , ‘ı’ , ‘IJ’ , ‘ij’ , ‘Ĵ’ , ‘ĵ’ , ‘Ķ’ , ‘ķ’ , ‘Ĺ’ , ‘ĺ’ , ‘Ļ’ , ‘ļ’ , ‘Ľ’ , ‘ľ’ , ‘Ŀ’ , ‘ŀ’ , ‘Ł’ , ‘ł’ , ‘Ń’ , ‘ń’ , ‘Ņ’ , ‘ņ’ , ‘Ň’ , ‘ň’ , ‘ʼn’ , ‘Ō’ , ‘ō’ , ‘Ŏ’ , ‘ŏ’ , ‘Ő’ , ‘ő’ , ‘Œ’ , ‘œ’ , ‘Ŕ’ , ‘ŕ’ , ‘Ŗ’ , ‘ŗ’ , ‘Ř’ , ‘ř’ , ‘Ś’ , ‘ś’ , ‘Ŝ’ , ‘ŝ’ , ‘Ş’ , ‘ş’ , ‘Š’ , ‘š’ , ‘Ţ’ , ‘ţ’ , ‘Ť’ , ‘ť’ , ‘Ŧ’ , ‘ŧ’ , ‘Ũ’ , ‘ũ’ , ‘Ū’ , ‘ū’ , ‘Ŭ’ , ‘ŭ’ , ‘Ů’ , ‘ů’ , ‘Ű’ , ‘ű’ , ‘Ų’ , ‘ų’ , ‘Ŵ’ , ‘ŵ’ , ‘Ŷ’ , ‘ŷ’ , ‘Ÿ’ , ‘Ź’ , ‘ź’ , ‘Ż’ , ‘ż’ , ‘Ž’ , ‘ž’ , ‘ſ’ , ‘ƒ’ , ‘Ơ’ , ‘ơ’ , ‘Ư’ , ‘ư’ , ‘Ǎ’ , ‘ǎ’ , ‘Ǐ’ , ‘ǐ’ , ‘Ǒ’ , ‘ǒ’ , ‘Ǔ’ , ‘ǔ’ , ‘Ǖ’ , ‘ǖ’ , ‘Ǘ’ , ‘ǘ’ , ‘Ǚ’ , ‘ǚ’ , ‘Ǜ’ , ‘ǜ’ , ‘Ǻ’ , ‘ǻ’ , ‘Ǽ’ , ‘ǽ’ , ‘Ǿ’ , ‘ǿ’ );
$b = array( ‘A’ , ‘A’ , ‘A’ , ‘A’ , ‘A’ , ‘A’ , ‘AE’ , ‘C’ , ‘E’ , ‘E’ , ‘E’ , ‘E’ , ‘I’ , ‘I’ , ‘I’ , ‘I’ , ‘D’ , ‘N’ , ‘O’ , ‘O’ , ‘O’ , ‘O’ , ‘O’ , ‘O’ , ‘U’ , ‘U’ , ‘U’ , ‘U’ , ‘Y’ , ‘s’ , ‘a’ , ‘a’ , ‘a’ , ‘a’ , ‘a’ , ‘a’ , ‘ae’ , ‘c’ , ‘e’ , ‘e’ , ‘e’ , ‘e’ , ‘i’ , ‘i’ , ‘i’ , ‘i’ , ‘n’ , ‘o’ , ‘o’ , ‘o’ , ‘o’ , ‘o’ , ‘o’ , ‘u’ , ‘u’ , ‘u’ , ‘u’ , ‘y’ , ‘y’ , ‘A’ , ‘a’ , ‘A’ , ‘a’ , ‘A’ , ‘a’ , ‘C’ , ‘c’ , ‘C’ , ‘c’ , ‘C’ , ‘c’ , ‘C’ , ‘c’ , ‘D’ , ‘d’ , ‘D’ , ‘d’ , ‘E’ , ‘e’ , ‘E’ , ‘e’ , ‘E’ , ‘e’ , ‘E’ , ‘e’ , ‘E’ , ‘e’ , ‘G’ , ‘g’ , ‘G’ , ‘g’ , ‘G’ , ‘g’ , ‘G’ , ‘g’ , ‘H’ , ‘h’ , ‘H’ , ‘h’ , ‘I’ , ‘i’ , ‘I’ , ‘i’ , ‘I’ , ‘i’ , ‘I’ , ‘i’ , ‘I’ , ‘i’ , ‘IJ’ , ‘ij’ , ‘J’ , ‘j’ , ‘K’ , ‘k’ , ‘L’ , ‘l’ , ‘L’ , ‘l’ , ‘L’ , ‘l’ , ‘L’ , ‘l’ , ‘l’ , ‘l’ , ‘N’ , ‘n’ , ‘N’ , ‘n’ , ‘N’ , ‘n’ , ‘n’ , ‘O’ , ‘o’ , ‘O’ , ‘o’ , ‘O’ , ‘o’ , ‘OE’ , ‘oe’ , ‘R’ , ‘r’ , ‘R’ , ‘r’ , ‘R’ , ‘r’ , ‘S’ , ‘s’ , ‘S’ , ‘s’ , ‘S’ , ‘s’ , ‘S’ , ‘s’ , ‘T’ , ‘t’ , ‘T’ , ‘t’ , ‘T’ , ‘t’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘W’ , ‘w’ , ‘Y’ , ‘y’ , ‘Y’ , ‘Z’ , ‘z’ , ‘Z’ , ‘z’ , ‘Z’ , ‘z’ , ‘s’ , ‘f’ , ‘O’ , ‘o’ , ‘U’ , ‘u’ , ‘A’ , ‘a’ , ‘I’ , ‘i’ , ‘O’ , ‘o’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘U’ , ‘u’ , ‘A’ , ‘a’ , ‘AE’ , ‘ae’ , ‘O’ , ‘o’ );
return str_replace ( $a , $b , $str );
>

function post_slug ( $str )
<
return strtolower ( preg_replace (array( ‘/[^a-zA-Z0-9 -]/’ , ‘/[ -]+/’ , ‘/^-|-$/’ ),
array( » , ‘-‘ , » ), remove_accent ( $str )));
>
?>

Example: post_slug(‘ -Lo#&@rem IPSUM //dolor-/sit — amet-/-consectetur! 12 — ‘)
will output: lorem-ipsum-dolor-sit-amet-consectetur-12

[Editor’s note: in this case it would be wise to rely on the preg_quote() function instead which was added for this specific purpose]

If your replacement string has a dollar sign or a backslash. it may turn into a backreference accidentally! This will fix it.

I want to replace ‘text’ with ‘$12345′ but this becomes a backreference to $12 (which doesn’t exist) and then it prints the remaining ’34’. The function down below will return a string that escapes the backreferences.

OUTPUT:
string(8) «some 345»
string(11) «some \12345»
string(8) «some 345»
string(11) «some $12345»

// Either of these will backreference and fail
$b1 = ‘\12345’ ; // Should be ‘\\12345’ to avoid backreference
$b2 = ‘$12345’ ; // Should be ‘\$12345’ to avoid backreference

$d = array( $b1 , $b2 );

foreach ( $d as $b ) <
$result1 = preg_replace ( ‘#(text)#’ , $b , $a ); // Fails
var_dump ( $result1 );
$result2 = preg_replace ( ‘#(text)#’ , preg_escape_back ( $b ), $a ); // Succeeds
var_dump ( $result2 );
>

// Escape backreferences from string for use with regex
function preg_escape_back ( $string ) <
// Replace $ with \$ and \ with \\
$string = preg_replace ( ‘#(? , ‘\\\\$1’ , $string );
return $string ;
>

If you want to catch characters, as well european, russian, chinese, japanese, korean of whatever, just :
— use mb_internal_encoding(‘UTF-8’);
— use preg_replace(‘`. `u’, ‘. ‘, $string) with the u (unicode) modifier

For further information, the complete list of preg_* modifiers could be found at :
http://php.net/manual/en/reference.pcre.pattern.modifiers.php

preg_replace (and other preg-functions) return null instead of a string when encountering problems you probably did not think about!
————————-


It may not be obvious to everybody that the function returns NULL if an error of any kind occurres. An error I happen to stumple about quite often was the back-tracking-limit:
http://de.php.net/manual/de/pcre.configuration.php
#ini.pcre.backtrack-limit

When working with HTML-documents and their parsing it happens that you encounter documents that have a length of over 100.000 characters and that may lead to certain regular-expressions to fail due the back-tracking-limit of above.

A regular-expression that is ungreedy («U», http://de.php.net/manual/de/reference.pcre.pattern.modifiers.php) often does the job, but still: sometimes you just need a greedy regular expression working on long strings .

Since, an unhandled return-value of NULL usually creates a consecutive error in the application with unwanted and unforeseen consequences, I found the following solution to be quite helpful and at least save the application from crashing:

= preg_replace ( ‘/some_regexp/’ , «replacement» , $string_before );

// if some error occurred we go on working with the unchanged original string
if ( PREG_NO_ERROR !== preg_last_error ())
<
$string_after = $string_before ;

// put email-sending or a log-message here
> //if

// free memory
unset( $string_before );

?>

You may or should also put a log-message or the sending of an email into the if-condition in order to get informed, once, one of your regular-expressions does not have the effect you desired it to have.

Take care when you try to strip whitespaces out of an UTF-8 text. Using something like:

= preg_replace ( «<\s+>» , ‘ ‘ , $text );
?>

brokes in my case the letter à which is hex c3a0. But a0 is a whitespace. So use

= preg_replace ( «<[ \t]+>» , ‘ ‘ , $text );
?>

to strip all spaces and tabs, or better, use a multibyte function like mb_ereg_replace.

$firstname = htmlspecialchars($_POST[‘campo’]);
$firstname = preg_replace(«/[^a-zA-Z0-9]/», «», $firstname, -1, $count_fn);

// $count_fn conta quantos caracteres foram mudados.
// $firstname variavel que captura o input

If you want to replace only the n-th occurrence of $pattern, you can use this function:

function preg_replace_nth ( $pattern , $replacement , $subject , $nth = 1 ) <
return preg_replace_callback ( $pattern ,
function( $found ) use (& $pattern , & $replacement , & $nth ) <
$nth —;
if ( $nth == 0 ) return preg_replace ( $pattern , $replacement , reset ( $found ) );
return reset ( $found );
>, $subject , $nth );
>

echo preg_replace_nth ( «/(\w+)\|/» , ‘$ <1>is the 4th|’ , «|aa|b|cc|dd|e|ff|gg|kkk|» , 4 );

?>

this outputs |aa|b|cc|dd is the 4th|e|ff|gg|kkk|
backreferences are accepted in $replacement

//. replace with anything that you can do with searched string.
//Marcin Majchrzak
//pixaltic.com

$c = «2 4 8» ;
echo ( $c ); //display:2 4 8

$cp = «/(\d)\s(\d)\s(\d)/e» ; //pattern
$cr = «‘\\3*\\2+\\1=’.((‘\\3’)*(‘\\2’)+(‘\\1’))» ; //replece
$c = preg_replace ( $cp , $cr , $c );
echo ( $c ); //display:8*4+2=34
?>

It may be useful to note that if you pass an associative array as the $replacement parameter, the keys are preserved.

= preg_replace ( ‘/foo/’ , ‘bar’ , [ ‘first’ => ‘foobar’ , ‘second’ => ‘barfoo’ ]);
// $replaced is now [‘first’ => ‘barbar’, ‘second’ => ‘barbar’].
?>

Wasted several hours because of this:

= ‘It’s a string with HTML entities’ ;
preg_replace ( ‘

e’ , ‘code2utf($1)’ , $str );
?>

This code must convert numeric html entities to utf8. And it does with a little exception. It treats wrong codes starting with &#0

The reason is that code2utf will be called with leading zero, exactly what the pattern matches — code2utf(039).
And it does matter! PHP treats 039 as octal number.
Try print( 011 ); ?>

Solution:
( ‘

e’ , ‘code2utf($1)’ , $str ); ?>

There seems to be some confusion over how greediness works. For those familiar with Regular Expressions in other languages, particularly Perl: it works like you would expect, and as documented. Greedy by default, un-greedy if you follow a quantifier with a question mark.

There is a PHP/PCRE-specific U pattern modifier that flips the greediness, so that quantifiers are by default un-greedy, and become greedy if you follow the quantifier with a question mark: http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

To make things clear, a series of examples:

= «a bunch of stuff this that and more stuff with a second code block then extra at the end» ;

$preview_default = preg_replace ( ‘/ (.*) /is’ , » $1 » , $preview );
$preview_manually_ungreedy = preg_replace ( ‘/ (.*?) /is’ , » $1 » , $preview );

$preview_U_default = preg_replace ( ‘/ (.*) /isU’ , » $1 » , $preview );
$preview_U_manually_greedy = preg_replace ( ‘/ (.*?) /isU’ , » $1 » , $preview );

echo «Default, no ?: $preview_default \n» ;
echo «Default, with ?: $preview_manually_ungreedy \n» ;
echo «U flag, no ?: $preview_U_default \n» ;
echo «U flag, with ?: $preview_U_manually_greedy \n» ;

Default, no ?: a bunch of stuff this that and more stuff with a second code block then extra at the end
Default, with ?: a bunch of stuff this that and more stuff with a second code block then extra at the end
U flag, no ?: a bunch of stuff this that and more stuff with a second code block then extra at the end
U flag, with ?: a bunch of stuff this that and more stuff with a second code block then extra at the end

As expected: greedy by default, ? inverts it to ungreedy. With the U flag, un-greedy by default, ? makes it greedy.

Warning: a common made mistake in trying to remove all characters except numbers and letters from a string, is to use code with a regex similar to preg_replace(‘[^A-Za-z0-9_]’, », . ). The output goes in an unexpected direction in case your input contains two double quotes.

echo preg_replace(‘[^A-Za-z0-9_]’, », ‘D»usseldorfer H»auptstrasse’)

It is important to not forget a leading an trailing forward slash in the regex:

echo preg_replace(‘/[^A-Za-z0-9_]/’, », ‘D»usseldorfer H»auptstrasse’)

PS An alternative is to use preg_replace(‘/\W/’, », $t) for keeping all alpha numeric characters including underscores.

If there’s a chance your replacement text contains any strings such as «$0.95», you’ll need to escape those $n backreferences:

function escape_backreference ( $x )
<
return preg_replace ( ‘/\$(\d)/’ , ‘\\\$$1’ , $x );
>
?>

as I wasn’t able to find another way to do this, I wrote a function converting any UTF-8 string into a correct NTFS filename (see http://en.wikipedia.org/wiki/Filename).

function strToNTFSFilename ( $string )
<
$reserved = preg_quote ( ‘\/:*?»<>‘ , ‘/’ );
return preg_replace ( «/([\\x00-\\x1f < $forbidden >])/e» , «_» , $string );
>
?>

It converts all control characters and filename characters which are reserved by Windows (‘\/:*?»<>‘) into an underscore.
This way you can safely create an NTFS filename out of any UTF-8 string.

Be aware that when using the «/u» modifier, if your input text contains any bad UTF-8 code sequences, then preg_replace will return an empty string, regardless of whether there were any matches.

This is due to the PCRE library returning an error code if the string contains bad UTF-8.

HackWare.ru

Этичный хакинг и тестирование на проникновение, информационная безопасность

Регулярные выражения в PHP (ч. 2)

Оглавление

Первая часть:

Вторая часть:

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

Общие типы символов

Теперь мы опять вернёмся к синтаксису, который может использоваться при написании регулярных выражений. В отличие от ранее рассмотренных основ, описанное ниже является более сложным и применяется реже, либо может быть описано с помощью уже рассмотренного синтаксиса.

Например, далее рассмотрены способы указания общего типа символов — некоторые из этих способов записи являются альтернативным синтаксисом к уже рассмотренным. Допустим если мы хотим указать в регулярном выражении «любая цифра», то мы можем использовать [0-9]. Также имеется ещё один вариант записи с помощью экранирующих последовательностей. «Любая десятичная цифра» в них обозначается как \d.

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

Среди экранирующих последовательностей есть элементы синтаксиса, который невозможно передать иным способом. Примеры будут показаны далее.

Общие типы символов обозначаются так:

\d

любая десятичная цифра

\D

любой символ, кроме десятичной цифры

\h

любой горизонтальный пробельный символ

\H

любой символ, не являющийся горизонтальным пробельным символом

\s

любой пробельный символ

\S

любой непробельный символ

\v

любой вертикальный пробельный символ

\V

любой символ, не являющийся вертикальным пробельным символом

\w

Любой символ, образующий «слово»

\W

Любой символ, не образующий «слово»

Каждая пара таких специальных последовательностей делит полное множество всех символов на два непересекающихся множества. Любой символ соответствует одному и только одному множеству из пары.

Следующие символы считаются как «пробельные»: HT (9), LF (10), FF (12), CR (13), и пробел (32). Тем не менее, если идет локале-зависимый поиск, и произойдет совпадение с символами в диапазоне 128-255, они также будут восприняты как пробельные, например NBSP (A0).

Символ, образующий «слово» — это произвольная цифра, буква или символ подчеркивания, проще говоря, любой символ, который может являться частью «слова» в Perl. Определение букв и цифр управляется символьными таблицами, с которыми была собрана PCRE. И, как следствие, эти наборы могут отличаться в различных локализированных дистрибутивах. Например, в локали «fr» (Франция) некоторые символы с кодом выше 128 используются для записи ударных символов и, соответственно, соответствуют маске \w.

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

У этих символов может быть весьма полезное применение. Давайте вспомним (чуть переделанное) регулярное выражение для вывода HTML тэга всех заголовков вместе с конечным тегом, а также вместе с самим содержанием заголовка:

Используя уже известный код:

я получил вот такой результат:

Найдено всего 15 совпадений, хотя мы помним, что на этой странице заголовков намного больше. Дело в том, что найдены только заголовки, которые в HTML коде записаны в одну строку, например так:

А если запись разбита на несколько строк, например так:

то такие заголовки найдены не были.

Проблема не в каких-то ограничениях регулярных выражений — в PHP анализ текста происходит именно целиком, то есть даже если текст состоит из нескольких строк, в PHP он анализируется за раз, без разбития на строки.

Проблема в нашем регулярном выражении, которое мы написали — мы не указали, что после открывающего тэга заголовка могут идти пробелы. Затем после содержимого заголовка также могут идти пробелы. Давайте составим новое регулярное выражение, с учётом этого. Любые пробельные символы обозначаются как \s. Их может не быть вовсе, а может быть несколько, поэтому в качестве квантора нужно использовать звёздочку, получаем \s*. Эту конструкцию вставляем два раза: 1) между открывающим HTML тэгом и содержимым заголовка; 2) между концом содержимого заголовка и закрывающим HTML тэгом.

Получаем такое регулярное выражение:

В результате находим 51 заголовок — видимо, это все заголовки анализируемой страницы, среди них как написанный в одну строку, так и многострочные.

В подобных случаях также можно использовать модификатор регулярного выражения s. Подробности и примеры смотрие в статье «Поиск по нескольким строкам в PHP с функциями preg_match_all и preg_match».

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

Непечатные символы в видимой форме в описании шаблона

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

\a

символ оповещения, сигнал, (BEL, шестнадцатеричный код 07)

\cx

«Ctrl+x«, где x — произвольный символ

\e

escape (шестнадцатеричный код 1B)

\f

разрыв страницы (шестнадцатеричный код 0C)

\n

перевод строки (шестнадцатеричный код 0A)

символ со свойством xx, подробнее смотрите свойства unicode

символ без свойства xx, подробнее смотрите свойства unicode

\r

возврат каретки (шестнадцатеричный код 0D)

\R

разрыв строки: совпадает с \n, \r и \r\n

\t

табуляция (шестнадцатеричный код 09)

\xhh


символ с шестнадцатеричным кодом hh

\ddd

символ с восьмеричным кодом ddd, либо ссылка на подмаску

Если быть более точным, комбинация «\cx» интерпретируется следующим образом: если «x» — символ нижнего регистра, он преобразуется в верхний регистр. После этого шестой бит символа (шестнадцатеричный код 40) инвертируется. Таким образом «\cz» интерпретируется как шестнадцатеричное значение 1A, в то время как «\c<" получает шестнадцатеричное значение 3B, а "\c;" - 7B.

После «\x» считываются еще две шестнадцатеричные цифры (они могут быть записаны в нижнем или верхнем регистре). В режиме UTF-8, разрешается использование «\x<. >«, где содержимое скобок является строкой из шестнадцатеричных цифр. Она интерпретируется как символ UTF-8 character с кодом, совпадающим с данным шестнадцатеричным числом. Исходная шестнадцатеричная экранирующая последовательность, \xhh, совпадает с двухбайтным UTF-8 символом, если его значение превышает 127.

После «\0» считываются две восьмеричные цифры. Если в записи менее двух цифр, будут использованы все фактически присутствующие цифры. Таким образом, последовательность «\0\x\07» будет интерпретирована как два бинарных нуля, за которыми следует символ оповещения (звонок). В случае, если вы используете представление числа в восьмеричном коде, убедитесь, что за начальным нулем следуют две значащие цифры.

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

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

\040

еще один способ записи пробела

\40

то же самое в случае, если данной записи предшествует менее сорока подмасок

\7

всегда интерпретируется как ссылка на подмаску

\11

может быть как обратной ссылкой, так и альтернативной записью символа табуляции

\011

всегда интерпретируется как символ табуляции

\0113

символ табуляции, за которым следует цифра «3»

\113

интерпретируется как символ с восьмеричным кодом 113 (так как ссылок на подмаски не может быть более чем 99)

\377

байт, всецело состоящий из единичных битов

\81

либо обратная ссылка, либо бинарный ноль, за которым следуют цифры «8» и «1»

Следует помнить, что восьмеричные значения, превышающие 100, следует писать без лидирующего нуля, так как читается не более трех восьмеричных цифр.

Все последовательности, определяющие однобайтное значение, могут встречаться как внутри, так и вне символьных классов. Кроме того, внутри символьного класса запись «\b» интерпретируется как символ возврата (‘backspace’, шестнадцатеричный код 08). Вне символьного класса она имеет другое значение (какое именно, описано ниже).

Определение формальных утверждений

Ещё одно использование обратного слеша — определение некоторых формальных утверждений, описывающих условия касательно месторасположения особых позиций в строке и совершенно не затрагивающих сами символы. Использование подмасок как более сложных формальных утверждений описано далее. Такими управляющими последовательностями являются:

\b

\B

не является границей слова

\A

начало данных (независимо от многострочного режима)

\Z

конец данных либо позиция перед последним переводом строки (независимо от многострочного режима)

\z

конец данных (независимо от многострочного режима)

\G

первая совпадающая позиция в строке

Описанные выше последовательности не могут встречаться в символьных классах (исключая комбинацию «\b«, которая внутри класса означает символ возврата ‘backspace’).

Границей слова считается такая позиция в строке, в которой из текущего и предыдущего символа только один соответствует \w или \W (т.е. один из них соответствует \w, а другой \W). Начало или конец строки также соответствуют границе слова в случае, если первый или, соответственно, последний символ совпадает с \w.

Специальные последовательности \A, \Z и \z отличаются от общеупотребляемых метасимволов начала строки ‘^‘ и конца строки ‘$‘ (описанных в разделе якоря первой части) тем, что они всегда совпадают либо в самом начале либо в самом конце строки. На них никак не влияют опции m (PCRE_MULTILINE) и D (PCRE_DOLLAR_ENDONLY). Разница между \Z и \z в том, что \Z соответствует позиции перед последним символом в случае, если последний символ — перевод строки, кроме самого конца строки. В то время, как \z соответствует исключительно концу данных.

Утверждение \G является истинным только в том случае, если текущая проверяемая позиция находится в начале совпадения, указанного параметром offset функции preg_match(). Она отличается от \A при ненулевом значении параметра offset.

\Q и \E могут быть использованы для игнорирования метасимволов регулярных выражений в шаблоне. Например: \w+\Q.$.\E$ совпадет с один или более символов, составляющих «слово»,за которыми следуют символы .$. и якорь в конце строки.

Последовательность \K может быть использована для сброса начала совпадения. Например, шаблон foo\Kbar совпадет с «foobar», но сообщит о том, что совпал только с «bar». Использование \K не мешает установке подмасок. Например, если шаблон (foo)\Kbar совпадет со строкой «foobar», первой подмаской все равно будет являться «foo».

POSIX нотация для символьных классов

Perl поддерживает нотацию POSIX для символьных классов. Это включает использование имен, заключенных в [: и :], в свою очередь заключенных в квадратные скобки. PCRE также поддерживает эту запись. Например, [01[:alpha:]%] совпадет с «0», «1», любым алфавитным символом или «%«. Поддерживаются следующие имена классов:

alnum буквы и цифры
alpha буквы
ascii символы с кодами 0 — 127
blank только пробел или символ табуляции
cntrl управляющие символы
digit десятичные цифры (то же самое, что и \d)
graph печатные символы, исключая пробел
lower строчные буквы
print печатные символы, включая пробел
punct печатные символы, исключая буквы и цифры
space пробельные символы(почти то же самое, что и \s)
upper прописные буквы
word символы «слова» (то же самое, что и \w)
xdigit шестнадцатеричные цифры

Класс пробельных символов (space) — это горизонтальная табуляция (HT, 9), перевод строки (LF, 10), вертикальная табуляция (VT, 11), разрыв страницы (FF, 12), возврат каретки (CR, 13) и пробел (32). Учтите, что этот список включает вертикальную табуляцию (VT, код 11). Это отличает «space» от \s, который не включает этот символ (для совместимости с Perl).

Название word — это расширение Perl, а blank — расширение GNU, начиная с версии Perl 5.8. Другое расширение Perl — это отрицание, которое указывается символом ^ после двоеточия. Например, [12[:^digit:]] совпадет с «1», «2», или с любой не-цифрой.

В режиме UTF-8, символы со значениями, превышающими 128, не совпадут ни с одним из символьных классов POSIX. Начиная с PHP 5.3.0 и libpcre 8.10 некоторые символьные классы изменены, чтобы использовать свойства символов Unicode, в этом случае упомянутое ограничение не применяется. Читайте руководство PCRE(3) для подробностей.

Подмаски

Подмаска — это часть регулярного выражения, которая участвует в поиске. Подмаска может выполнять несколько функций:

1) если была найдена строка, соответствующая целому регулярному выражению, то в результаты поиска будут возвращены две строки: во-первых, соответствующая всему регулярному выражению, и, во-вторых, соответствующая подмаске

2) найденная в подмаске строка может вновь использоваться в регулярном выражении в качестве обратной ссылке (о них позже)

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

Подмаски могут быть вложенными одна в другую.

При использовании функции preg_match_all возвращается массива, где в качестве первого элемента (с индексом 0) возвращается массив с найденными значениями строк. Если указаны подмаски, то в качестве второго элемента возвращаемого массива (с индексом 1) будет массив с найденными строками, соответствующими первой подмаске. Если используется две подмаски, то будет возвращён ещё один массив и так далее для каждой последующей подмаске.

Как мы помним из первой части, описывающий синтаксис регулярных выражений, скобки имеют и другое значение: или использовании оператора | (ИЛИ) они ограничивают варианты альтернатив друг от друга. Например, шаблон cat(aract|erpillar|) соответствует одному из слов «cat», «cataract» или «caterpillar». Без использования скобок он соответствовал бы строкам «cataract», «erpillar» или пустой строке.

То есть скобки выполняют одновременно две функции.

На самом деле выполнение одновременно двух функций не всегда удобно. Бывают случаи, когда необходима группировка альтернатив без захвата строки. В случае, если после открывающей круглой скобки следует «?:«, захват строки не происходит, и текущая подмаска не нумеруется. Например, если строка «the white queen» сопоставляется с шаблоном the ((?:red|white) (king|queen)), будут захвачены подстроки «white queen» и «queen», и они будут пронумерованы 1 и 2 соответственно. Максимальное количество захватывающих подмасок — 65535. Такие большие шаблоны могут не скомпилироваться, в зависимости от настроек libpcre.

В случае, если в незахватывающей подмаске необходимо указать дополнительные опции, можно воспользоваться удобным сокращением: символ, обозначающий устанавливаемую опцию помещается между «?» и «:«. Таким образом, следующие два шаблона

соответствуют одному и тому же набору строк. Поскольку альтернативные версии берутся слева направо, и установленные опции сохраняют своё действие до конца подмаски, опция, установленная в одной ветке, также имеет эффект во всех последующих ветках. Поэтому приведенные выше шаблоны совпадают как с «SUNDAY», так и с «Saturday».

Также можно использовать именованные подмаски с помощью синтаксиса (?P pattern). Эта подмаска будет индексирована в массиве совпадений кроме обычного числового индекса, еще и по имени name. В PHP 5.2.2 было добавлено два альтернативных синтаксиса: (? pattern) и (?’name’pattern).

Иногда бывает необходимо иметь несколько совпадений, исключающих друг друга. Обычно, каждое такое совпадение получает свой собственный номер, даже если шаблон позволяет совпасть только одному из них. Синтаксис (?| позволяет обойти это поведение и убрать дублирующиеся номера. Рассмотрим следующее регулярное выражение, сопоставленное со строкой Sunday:

Здесь Sun сохраняется в ссылке 2, тогда как ссылка 1 пуста. Если же совпадет Sat, то она будет помещена в ссылку 1, а ссылка 2 вообще не будет существовать. Использование (?| в шаблоне решает эту проблему:

В этом шаблоне обе подмаски Sun и Sat будут сохранены под номером 1.

Обратные ссылки в PHP

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

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

Однако, в случае, если следующее за обратным слешем число меньше 10, оно всегда интерпретируется как обратная ссылка, и приводит к ошибке только в том случае, если нет соответствующего числа открывающих скобок. Другими словами, открывающие скобки не обязаны предшествовать ссылке для чисел меньше 10. «Упреждающая обратная ссылка» может иметь смысл, если используется повторение и более поздняя подмаска участвует в ранней итерации. Более детальную информацию об обработке цифр после обратного слеша можно найти в разделе «Обратный слеш».

Обратная ссылка сопоставляется с частью строки, захваченной соответствующей подмаской, но не с самой подмаской. Таким образом шаблон (sens|respons)e and \1ibility соответствует «sense and sensibility», «response and responsibility», но не «sense and responsibility». В случае, если обратная ссылка обнаружена во время регистрозависимого поиска, то при сопоставлении обратной ссылки регистр также учитывается. Например, ((?i)rah)\s+\1 соответствует «rah rah» и «RAH RAH», но не «RAH rah», хотя сама подмаска сопоставляется без учета регистра.

На одну и ту же подмаску может быть несколько ссылок. Если подмаска не участвовала в сопоставлении, то сопоставление со ссылкой на нее всегда терпит неудачу. Например, шаблон (a|(bc))\2 терпит неудачу, если находит соответствие с «a» раньше, чем с «bc». Поскольку может быть до 99 обратных ссылок, все цифры, следующие за обратным слешем, рассматриваются как часть потенциальной обратной ссылки. Если за ссылкой должна следовать цифра, необходимо использовать ограничитель. В случае, если указан флаг x (PCRE_EXTENDED), ограничителем может быть любой пробельный символ. В противном случае можно использовать пустой комментарий.

Ссылка на подмаску, внутри которой она расположена, всегда терпит неудачу, если это первое сопоставление текущей подмаски. Например, шаблон (a\1) не соответствует ни одной строке. Но все же такие ссылки бывают полезны в повторяющихся подмасках. Например, шаблон (a|b\1)+ совпадает с любым количеством «a», «aba», «ababaa». При каждой итерации подмаски обратная ссылка соответствует той части строки, которая была захвачена при предыдущей итерации. Чтобы такая конструкция работала, шаблон должен быть построен так, чтобы при первой итерации сопоставление с обратной ссылкой не производилось. Этого можно достичь, используя альтернативы (как в предыдущем примере), либо квантификаторы с минимумом, равным нулю.

Начиная с PHP 5.2.2, управляющая последовательность \g может быть использована для абсолютных и относительных ссылок на подмаски. После этой последовательности должно быть указано беззнаковое или отрицательное число, при желании заключенное в фигурные скобки. Последовательности \1, \g1 и \g эквивалентны друг другу. Использование этого шаблона с беззнаковым числом поможет избежать двусмысленности, присущей числам после обратного слеша. Это также помогает отличить обратные ссылки от символов в восьмеричном формате, а также упрощает запись числового литерала сразу после обратной ссылки, например, \g<2>1.

Использование отрицательных чисел с \g полезно при использовании относительных ссылок. Например, (foo)(bar)\g соответствует «foobarbar», а (foo)(bar)\g соответствует «foobarfoo». Это также может быть полезно в длинных шаблонах, в качестве альтернативы отслеживания числа подмасок, на которые можно ссылаться в последующей части шаблона.

Указать обратную ссылку на именованную подмаску можно с помощью (?P=name) или, начиная с PHP 5.2.2, \k или \k’name‘. Кроме того, в PHP 5.2.4 была добавлена поддержка \k> и \g>, а в PHP 5.2.7 для \g и \g’name’.

К примеру, я хочу найти строки, состоящие из пяти любых, но одинаковых цифр, например, «11111», «22222» и так далее, в этом случае я могу написать следующее регулярное выражение:

Как мы рассмотрели чуть выше, экранирующая последовательность \d обозначает любую цифру. Для того, чтобы найденную строку можно было использовать в качестве обратной ссылке, мы заключаем эту часть регулярного выражения в круглые скобки. То есть получается, что мы создаём подмаску в регулярном выражении. Затем идёт обратный слэш \ с цифрой 1 — это и есть обратная ссылка. То есть, что бы ни было найдено в первой подмаске, его значение будет помещено в обратную ссылку \1. Затем ещё идут три таких же обратных ссылки. Получается что регулярное выражение ищет любую цифру, за которой ещё четыре раза идёт эта же самая цифра.

Для поиска возьмём строку:

даст следующий результат:

В первый элемент массива помещён массив с найденными строками из пяти цифр. Во второй элемент массив помещён массив, соответствующий подмаскам — то есть одиночным цифрам. Но взяты не любые одиночные цифры — совпавшие значения подмасок взяты только в тех случаях, когда весь шаблон совпал со строкой.

Рассмотрим более практический пример. Допустим мы хотим найти в HTML коде все пары тэгов: открывающий и закрывающий тэг, между которыми идёт какой-либо текст. Есть исключения (например,
, и так далее) — но не будем их рассматривать, чтобы не усложнять пример.

Тэг абзаца выглядит примерно так:

Тэг раздела страницы:

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

Любая буква в угловых скобках обозначается так:

Чтобы создать обратную ссылку, поместим ту часть выражения, которая обозначает буквы, в круглые скобки:

Закрывающим тэгом будет обратная ссылка, содержащая найденное название тэга, помещённая между , то есть:

Поскольку в качестве разделителя используется слэш, то тот слэш, который означает «буквальный слэш» нужно экранировать, чтобы он потерял своё специальное значение и стал трактоваться как буквальный символ, получаем:

Составленное регулярное выражение будет соответствовать тэгам в следующем написании:

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

Помещаем эту конструкцию в ранее составленное регулярное выражение в то место, где могут быть атрибуты:

Функции PHP для поиска и замены по регулярному выражению

Рассмотренные ранее функции ищут строки по регулярному выражению (preg_match_all), либо проверяют, строку на соответствие регулярному выражению (preg_match). В случае, если нужно не просто найти строку, но и заменить её, используются следующие функции:

  • preg_filter — Производит поиск и замену по регулярному выражению
  • preg_replace_callback_array — Выполняет поиск и замену по регулярному выражению с использованием функций обратного вызова
  • preg_replace_callback — Выполняет поиск по регулярному выражению и замену с использованием callback-функции
  • preg_replace — Выполняет поиск и замену по регулярному выражению

В результате работы функции preg_replace, если найдены совпадения, возвращается новая версия subject, иначе subject возвращается нетронутым. Функция preg_filter() идентична функции preg_replace() за исключением того, что возвращает только те значения (возможно, преобразованные), в которых найдено совпадение. Подробнее о работе функций читайте по приведённым выше ссылкам.

Функция preg_replace_callback позволяет делать интеллектуальную замену. Её суть заключается в том, что не просто выполняется замена найденной строки, а вызывается функция, которой передаётся совпавшая строка, и эта функция уже и возвращает строку с заменой. Вместо элементарной замены, функция может, например, делать дополнительную проверку полученных данных и уже на основе принятого решения выполнять ту или иную замену. Можно установить счётчик и делать замену в каждом n-ной совпавшей строке — например, в каждой третьей или каждой десятой. Можно пронумеровать найденные строки и делать любые другие изменения, которые не ограничиваются обычным поиском и заменой на фиксированную строку.

Пример использование функции preg_replace_callback:

В этом примере из монотонной строки будут выбраны имена и каждое имя будет напечатано по отдельности. Для третьего имени будет написано, что это третье имя, для каждого десятого имени будет написано, что его номер кратен 10:

Пример моего реального недавнего использования функции preg_replace_callback на практике — добавления рекламы в каждый десятый комментарий — с её помощью очень легко реализовать подобную логику.

Другие функции PHP для работы с регулярными выражениями

  • preg_last_error — Возвращает код ошибки выполнения последнего регулярного выражения PCRE
  • preg_quote — Экранирует символы в регулярных выражениях
  • preg_split — Разбивает строку по регулярному выражению

Когда не нужно использовать регулярные выражения

Не используйте функцию preg_match(), если необходимо проверить наличие подстроки в заданной строке. Используйте для этого strpos() поскольку она выполнит эту задачу гораздо быстрее.

Если вам не нужна мощь регулярных выражений, то вместо preg_split вы можете выбрать более быстрые (хоть и простые) альтернативы наподобие explode() или str_split().

Поиск и замена с помощью регулярного выражения

Я пытаюсь выполнить поиск по тексту для определенного слова, а затем добавить тег html вокруг этого слова. Например, если бы у меня была строка «Я пошел в магазин, чтобы купить яблоки и апельсины» и хотел добавить ярлыки html bold вокруг яблок.

Проблема, слово i, ищущее строку с, хранится в текстовом файле и может быть прописным, строчным и т.д. Когда я использую preg_replace для этого, я могу заменить его правильно, добавив теги, но, например, если бы я искал Яблоки и строка, содержащая «яблоки», изменили форматирование с яблок на APPLES, я хочу, чтобы формат оставался прежним.

Я попытался использовать preg_replace, но я не могу найти способ сохранить один и тот же слот. Это то, что у меня есть:

Итак, если значение $было APPLES, оно изменило бы каждый формат яблок в строке $на верхний регистр из-за $replacemant, имеющего в нем значение $, которое является «APPLES».

Как я могу достичь этого, если формат case остается таким же и не нужно делать несколько циклов с разными версиями формата case?

Вместо использования $value verbatim в замещении вы можете использовать литеральные строки \0 или $0 . Точно так же, как \n / $n , для некоторого целого n возвращается обратно в n th группу захвата круглых скобок, \0 / $0 разворачивается до полного соответствия. Таким образом, у вас будет

Обратите внимание, что ‘$0‘ использует одинарные кавычки. Здесь вы можете избежать двойных кавычек, потому что $0 не интерпретируется как ссылка на переменную, но я думаю, что это яснее. В общем, вы должны быть осторожны с использованием $ внутри строки с двойными кавычками, так как вы часто получаете ссылку на существующую переменную, если не выйдете из $ как \$ . Аналогично, вы должны избегать обратной косой черты в \b внутри двойных кавычек для шаблона; хотя в этом конкретном случае это не имеет значения, в общем случае обратная косая черта является значимым символом в двойных кавычках.

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

Илон Маск рекомендует:  Что такое код windows
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL