Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

RegExp

.pdf
Скачиваний:
6
Добавлен:
11.03.2016
Размер:
443.18 Кб
Скачать

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

в

веб-программировании

Котова Екатерина

Школа Программирования

prog-school.ru

Задачи программирования.

Задачи, связанные с обработкой текста, встают повсеместно.

В общем случае, это задачи типа: o проверки входных данных o поиска фрагментов текста o замены вхождений

o и др.

Знакомо, не правда ли?

Конкретный пример – найти в тексте все адреса электронной почты и номера телефонов. Как Вы будете искать? С номерами у нас хотя бы есть ограничение по числу цифр, а вот с адресами уже сложнее. Можно, конечно, искать вхождения знака @ и определять символы справа и слева между, скажем, пробелами, если Вам точно известен стиль анализируемого текста, и наличие этих пробелов. Но, если подобная задача встанет повторно, Вы все равно придете к необходимости более глубокого анализа - анализа на соответствие шаблону адреса (имя@домен.домен верхнего уровня) и реализации посимвольного разбора текста.

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

Пожалуй, 2 задачи можно выделить как основные. Это:

1)тестирование на соответствие маске и

2)замена по шаблону.

При этом шаблон поиска может быть как простой строкой («кот»), так и абстрактным описанием множества строк, таким как шаблон почтового адреса в приведенном выше примере.

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

Регулярные выражения в веб-программировании @ prog-school.ru

1

Механизм регулярных выражений.

Определим нашу задачу так. Есть текст, который нужно обработать, и есть требование, как его обрабатывать. Исходя из требования, мы описываем некоторый шаблон. А дальше передаем шаблон и текст программе, которая сделает разбор за нас. То есть задача сводится к тому, чтобы сформировать шаблон. Насколько бы сложно это ни было, согласитесь, избавление себя от реализации разбора самостоятельно будет того стоить.

Таким образом, выходит, что регулярные выражения – это некая система разбора текста по указанным нами правилам, которые мы передаем ей в виде строки-шаблона.

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

Взглянем на определение из Википедии.

Регуля́рные выраже́ния (англ. regular expressions , сокр. RegExp, RegEx, жарг.

регэ́кспы или ре́гексы ) — это формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов (символов-джокеров, англ. wildcard characters). По сути это строка-образец (англ. pattern, по-русски еѐ часто называют «шаблоном», «маской»), состоящая из символов и метасимволов и задающая правило поиска.

Регулярные выражения еще называют «язык внутри языка». Надеюсь, теперь Вам понятен смысл этих слов.

Если понятия «формальный язык», «правило поиска», «синтаксический разбор» Вам не знакомы, и Вы хотите называть себя специалистом, стоит обратить внимание на такой раздел высшей математики, как теорию формальных языков (ТФЯ). Ведь это и есть математическая основа информатики. Понимание этих основ поможет Вам взглянуть на программирование под другим углом, и осознать, что программа – это точно работающий механизм.

Регулярные выражения в веб-программировании @ prog-school.ru

2

Семантика регулярного выражения.

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

Любое регулярное выражение состоит из символов двух типов:

1)обычные символы (литералы) - константы и

2)спецсимволы (метасимволы) - операторы.

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

Метасимволы - это инструкции для языка регулярных выражений, которые:

1)определяют порядок поиска,

2)задают тип символов искомой строки,

3)определяют способ окружения искомой строки в тексте,

4)определяют количество символов отдельного типа,

5)указывают интерпретатору выражения на дополнительные условия и ограничения.

Говоря языком ТФЯ, регулярные выражения состоят из констант и операторов, которые определяют множества строк и множества операций на них соответственно.

Рассмотрим базовые операции и правила:

1)конкатенация («и»)

Пример: заменить в тексте все слова «собака» на слово «кошка». Регулярное выражение для поиска: собака (конкатенация символов с о б а к а).

2)| дизъюнкция («или»)

Пример: заменить все слова «кошка» или «собака» на «зверь». Регулярное выражение для поиска: собака|кошка.

3)( )

Пример: заменить tom@yandex.ru и tom@ya.ru на tom@gmail.com

Регулярное выражение для поиска: tom@(yandex|ya).ru

4)+ повторение предыдущего символа один или большее количество раз

Пример: убрать все лишние буквы «б» в словах «соббббака», «соббака». Регулярное выражение для поиска: соб+ака

5)* повторение предыдущего символа ноль или большее количество раз

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

собб*ака

6)? ноль или один раз

7)$ и ^ указание, искать в конце или начале строки

Пример: регулярное выражение ^собака определит вхождение в предложении «Собака – друг человека», и пропустит в «Я и моя собака – настоящие друзья»

Регулярные выражения в веб-программировании @ prog-school.ru

3

8)\d цифра от 0..9

Пример: найти все 4-хзначные номера. Регулярное выражение для поиска: \d\d\d\d

9)\s пробел

10)\D не цифра

11)\S одиночный символ

12)[ ] набор символов

13)[a-z] любой символ в указанном диапазоне

ит.д.

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

Еще один пример: необходимо реализовать проверку правильности ввода e-mail.

Регулярное выражение: [0-9a-z_]+@[0-9a-z_^.]+.[a-z]{2,3}/i.

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

иимеют следующие значения:

1)модификатор "g" — задаѐт поиск в строке как "глобальный"

2)модификатор "i" — задаѐт поиск в строке без учѐта регистра

3)―m‖ – для многострочного поиска

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

Регулярные выражения в веб-программировании @ prog-school.ru

4

Поддержка регулярных выражений в JavaScript.

ВJavaScript возможно два пути использования регулярных выражений:

1)с помощью методов объекта RegExp или

2)с помощью методов объекта String (search, match, replace).

Сами выражения имеют особую краткую форму и стандартный синтаксис.

Объект RegExp.

Объект RegExp инициализируется строкой регулярного выражения и инкапсулирует функции обработки текста.

Инициализацию объекта можно осуществить двумя способами - явным и косвенным:

// явный способ

var re = new RegExp("pattern"[, флаги]);

// косвенный (альтернативный) способ var re = /pattern/флаги;

где

pattern - регулярное выражение для поиска,

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

Первый способ используется часто (по мне, так он и наглядней), второй - иногда.

Вызовы, представленные ниже эквивалентны:

var reg = /ab+c/i

var reg = new RegExp("ab+c", "i")

и

var reg = new RegExp("\\w+") // ‘\’ дублируется, тк выражение взято в кавычки var reg = /\w+/

При косвенном способе шаблон задаѐтся без кавычек.

Методы RegExp.

В объекте RegExp определены следующие методы:

1)test() – для проверки результатов

2)exec() – для поиска совпадений

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

var reg = /\d/g;

var text = "Маша купила 2 яблока, 3 апельсина и 1 персик"; // проверим, наличие цифр в строке

if (reg.test(text))

alert("В строке есть цифры!");

Если нужно получить массив совпадений, применяется exec. Если совпадений нет, exec вернет null.

Регулярные выражения в веб-программировании @ prog-school.ru

5

// в случае обнаружения цифр, выведем их в порядке нахождения var item = null;

while ((item = reg.exec(text)) != null) alert(item[0]);

Обратите внимание, если вызвать эти функции подряд, функция exec вернет

3, 1,

а не

2, 3, 1.

Это произойдет потому, что методы RegExp во время выполнения обновляют свойства своего объекта. Одним из таких свойств является индекс конца последнего поиска lastIndex. Следующий поиск начинается от lastIndex.

Метод test() прекратит анализ после обнаружения цифры 2, а exec() с этого места начнет, поэтому 2-ка будет проигнорирована.

Теперь поясню, почему в функции alert стоит item[0], и почему мы вызываем exec в цикле. Метод exec возвращает массив вложенных совпадений. Те, найдя очередное совпадение, функция меняет lastIndex и начинает анализировать фрагмент строки в глубину. Убедимся на примере.

var reg = /a+(b+(c+))/g; var text = "abc aabbbcc"; var item = null;

var item_results;

while ((item = reg.exec(text)) != null)

{

item_results = item[0] + ": ";

for(var i = 1; i < item.length; i++) item_results += item[i] + " ";

item_results += " lastIndex= " + reg.lastIndex; alert(item_results);

}

Получим:

abc: bc c lastIndex= 3

aabbbcc: bbbcc cc lastIndex= 11

Методы String.

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

Методы класса String, работающие с регулярными выражениями:

1)search(regexp) – аналогичен методу RegExp.test()

2)match(regexp) - аналогичен методу RegExp.exec()

3)replace

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

Регулярные выражения в веб-программировании @ prog-school.ru

6

Эквивалентные записи:

str.search(new RegExp("\\s","g")) str.search(/\s/) str.search("\\s")

Метод search(regexp) возвращает индекс регулярного выражения в строке, или -1.

var regexp = /\d/g;

var text = "Маша купила 2 яблока, 3 апельсина и 1 персик"; // проверим, наличие цифр в строке

if (text.search(regexp) != -1) alert("В строке есть цифры!");

Метод match(regexp) вернет тот же результат, что и regexp.exec(text), ecли в regexp

нет флага g.

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

var reg1 = /a+(b+(c+))/g; var reg2 = /a+(b+(c+))/; var text = "abc aabbbcc";

alert("search1: " + text.match(reg1) + "; " + "search2: " + text.match(reg2));

Рузультат:

search1: abc,aabbbcc; search2: abc,bc,c

Как видно из примера, результат text.match(reg2)) соответсвует результату однократного вызова reg1.exec(text).

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

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

var newString = str.replace(regexp/substr, newSubStr/function), где

regexp – объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2

substr – строка, которая будет заменена на newSubStr.

newSubStr – строка, которая заменяет подстроку из аргумента номер 1.

function – функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).

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

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

В строке замены могут быть такие спецсимволы: $$ - вставляет «$» $& - вставялет найденную подстроку

$’ – вставляет часть строки, которая идет после найденного вхождения

Регулярные выражения в веб-программировании @ prog-school.ru

7

$n – вставляет подстроку вхождения, запомненную n-й вложенной скобкой

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

Первый параметр функции - найденная подстрока.

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

newString = "my XXzz".replace(/(X+)(z+)/, my_func)

function my_func(str, p1, p2, offset, s)

{

return p1 + ", " + p2;

}

Результат: my XX, zz

Регулярные выражения в веб-программировании @ prog-school.ru

8

Поддержка регулярных выражений в PHP.

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

1)preg_grep - возвращает вхождения массива, совпадающие с паттэрном

2)preg_match_all - выполняет глобальный поиск совпадений регулярного выражения

3)preg_match - выполняет поиск совпадений регулярного выражения

4)preg_quote - закавычивает символы регулярного выражения

5)preg_replace_callback - выполняет поиск регулярного выражения и замену с использованием обратного вызова/callback

6)preg_replace - выполняет поиск регулярного выражения и замену

7)preg_split - делит строку регулярным выражением

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

Рассмотрим выборочно некоторые из них.

int preg_match(string pattern, string subject [, array matches [, int flags]])

Ищет в subject совпадения с регулярным выражением, заданным в pattern.

Если matches предоставлен, он заполняется результатами поиска. $matches[0] будет содержать текст, совпавший со всем патэрном, $matches[1] будет содержать текст, совпавший первым захваченным субпатэрном в скобках, и так далее.

flags может быть только один: PREG_OFFSET_CAPTURE

Если этот флаг установлен, для каждого найденного совпадения будет возвращаться сопутствующее строковое смещение. Заметьте, что это изменяет return-значение в массиве, где каждый элемент является массивом, состоящим из совпавшей строки и в смещении 0 и еѐ строковым смещением в subject в смещении 1. Этот флаг доступен, начиная с PHP 4.3.0.

Параметр flags доступен, начиная с PHP 4.3.0.

preg_match() возвращает количество совпадений pattern. Это будет либо 0 раз (нет совпадений), либо 1 раз, поскольку preg_match() остановит поиск после первого найденного совпадения. preg_match_all(), наоборот, продолжит поиск до достижения конца subject. preg_match() возвращает FALSE при возникновении ошибки.

Пример: получить имя хоста из url.

// получить имя хоста из URL preg_match("/^(http:\/\/)?([^\/]+)/i", "http://www.php.net/index.html", $matches); $host = $matches[2];

// получить два последних сегмента имени хоста preg_match("/[^\.\/]+\.[^\.\/]+$/",$host,$matches); echo "domain name is: ".$matches[0]."\n";

Результат:

domain name is: php.net

array preg_split (string pattern, string subject [, int limit [, int flags]])

Регулярные выражения в веб-программировании @ prog-school.ru

9

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]