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

Nov 16, 2011 22:50

Новая задача привела к необходимости войти в тёмный лес под названием "регулярные выражения".

Увидев, как это выглядит, ужаснулась: /^(?:http:\/\/)?[-0-9a-z._]*.\w{2,4}[:0-9]*$/  
WTF?????
Прочитав статью, написанную, кстати, доходчиво (ссылку приведу ниже), ужаснулась ещё больше.

Попробую разложить всё по полочкам, описать, как я это вижу.

  Регулярные выражения(РВ) нужны для поиска данных в соответствии с определенными правилами (шаблонами). Это может быть поиск цифр в строке, поиск определенных буквенных сочетаний и прочее. Возможно, у них есть и больше функций, но пока не буду с этим заморачиваться. В моей задачке мне необходимо в двумерном массиве найти и вывести на экран номера строк, содержащих двузначные числа. Для поиска этих чисел я и попытаюсь использовать РВ.
  Итак, поехали:
Есть 2 типа символов:
1) Литералы - это буквы, цифры 0-9, знаки (+, -, , ,! и т.д) -т.е все те данные, которые могут присутствовать в строке и которые нам надо найти.
2) метасимволы - любые специальные символы

С литералами всё ясно, на метасимволах остановлюсь подробнее:
//для удобства:
зеленый - исходный набор символов
фиолетовый - нужное слово
 синий - РВ

Метасимволы:

* - может быть сколько угодно любых символов. А может и не быть вообще. Пример: из набора "авпорпслово" нужно найти "слово". Как будет выглядеть РВ: *слово*. Т.е на месте звёздочки может идти сколько угодно любых символов, а может и ничего не быть.

? - Любой единичный символ. Но для совпадения этот любой символ должен присутствовать. Пример: Из данного набор символов: "fdgfdсловоhfd" можно найти "слово" вот по такому РВ: *сл?во*. Но если написать *сло?во*, то совпадений не будет, т.к символ должен быть.

//ещё хочу остановиться на таком моменте: если звездочка в конце не указана, то после нужной комбинации не может стоять никаких символов. Т.е если у нас задан шаблон *слово, то совпадение будет в комбинации jhgjfdgслово, но не в hfdjgfсловоjhfdj. То же относится и к началу.

[] - символьный класс 
Как используем: Нам нужно найти либо букву i либо букву a в слове giraff. Искать будем с помощью символьного класса, а именно: [ia]. Эта комбинация должна найти любую из двух букв. Также можно использовать для поиска любой буквы или любой цифры: [a-z], [а-я], [0-9]. Стоит также отметить, что тут учитывается регистр. Если мы хотим задать любую букву алфавита, то надо писать так: [a-zA-Z].
Еще раз обратим внимание на то, что данные символьные классы описывают только один символ.

Чтобы указать количество символов, существуют квантификаторы. Допустим, нам надо, чтобы подряд шли 3 любых маленьких латинских буквы и 2 цифры. Можно описать так: [a-z][a-z][a-z][0-9][0-9] или же с помощью квантификаторов: [a-z]{3}[0-9]{2}. Тут вроде все просто.

Какие ещё символы (наверное, метасимволы, да простят мне мего-программеры, если ошибаюсь) используются для указания количества элементов:

* - уже было выше. Любое количество символов (от нуля до бесконечности). Например [a-z]* - это сколько угодно символов латинского алфавита. А может и вообще ни одного.
+ - Не менее одного символа. [a-z]+  - сколько угодно символов, но не меньше одного.
, - от и до. [a-z]{2,5} - любых символов данного класса должно быть от 2 до 5. Или [a-z]{2,} - сколько угодно, но не менее 2-х.
? - Не больше одного символа. Тут всё понятно, напишу только пример: [a-z]?.
^ - отрицание, исключение. Т.е все символы, кроме перечисленных. Пример: [^a-e785] - все символы, кроме a-e, 7,8,5. 
Скопирую классный примерчик с сайта, с котрого беру всю эту инфу:
abcdefg
abcddefg
abcdddefg
abcddddefg

Требование: Написать условие поиска совпадения для всех строк.

Решение: abcd{1,4}efg

Далее более сложные примеры использования символьных классов:
[a-cx-z1-3579] - Этот символ может быть буквой a,b,c,x,y,z или цифрой 1,2,3,5,7,9. Если я правильно поняла, цифры можно указывать только однозначные. Для двузначных (моя задача) будет что-то вроде [1-9][0-9].

Также можем указывать различные знаки. Тут всё понятно. Остановиться надо на знаке "-". Чтобы это был минус, а не интервал, указываем его в самом начале: [-a-z].

Начало и конец строки поиска обозначается символами ^ и $ соотвестсвенно. То, что заключено между этими символами ищется целой строкой. Т.е не одну букву из данной строки, а всю строку целиком.

По поводу крышечки ^: Перед квадратной скобкой - начало строки, после квадратной скобки - отрицание, в середине - просто литерал.

\s - пробел, табуляция, перевод строки (невидимый символ)
\S - любой видимый символ. Тоже самое, что ^\s.
\w - обычно буквы a-zA-Z и _. Тоже самое, что [a-zA-Z_]
\W - наборот. Всё, что не входит в \w
\d - все цифры
\D - все нецифры:)
. - все символы. Чтобы поставить именно точку (в качестве литерала): \.
\ - делает из любого спецсимвола литерал. Чтобы использовать \ в качестве литерала: \\
(Чтобы поставить \\, их надо удвоить: \\\\)

( ) - круглые скобки. Нужны для того, чтобы не просто проверить соответствие, но и запомнить его. Т.е нам нужно найти любую цифру, мы пишем [0-9]. Если же нам надо запомнить, что именно за цифра была, то ([0-9]).

Для запоминания данных комбинаций используются специальные переменные: \1 - первая комбинация, выделенная круглыми скобками, \2 - вторая и т.д.
\0 - запоминает всю совпавшую комбинацию.

Пример:
Регулярка задана так: [0-9]{2}([a-z]{3})([^a-c]{2}). 
Совпавшая комбинация: 23asdgh.
В \0 пойдет 23asdgh
В \1 будет asd
В \2 будет gh.

В программировании РВ оформляются так: /РВ/. (Можно использовать и другие ограничители. В этом ещё не разобаралась, вернусь позже. Пока остановимся на слэшах)

Альтернатива (Или). Если условию поиска может удовлетворять одна из двух комбинаций или символьных классов, используем знак | (вертикальная черта). Комбинации же заключаются в круглые скобки. К примеру: Нам нужно найти трёхзначное число или сочетание двух букв из диапазон а...ф. Запишем: ([0-9]{3})|([а-ф]{2}).
Результат будет тру, если поиск найдет, допустим, чило 567 ИЛИ сочетание "лс".  
Если надо выбрать между двумя одиночными литералами, то записываем в виде: (t|k).

Уточнение:  Как писалось выше, значения, совпадающие с заключенными в скобки регулярками, сохраняются в специальные переменные. Что делать, если нам это не нужно? Последовательность ?:
 Пример использования: (?:abc)|(?:def)

Теперь о php функциях, которые работают с регулярными выражениями:

preg_replace - заменить
preg_match - найти соответствие
preg_split - разбить

Как оформляются такие функции? Примеры опять сопру со статьи:

preg_match("шаблон_поиска", "строка_в_которой_проводится_поиск", массив_с_результами_поиска).

preg_match("/^[a-z0-9]/", $string,$mathces)

Написано исходя вот из этой статьи: http://phpclub.ru/detail/article/regexp_1

может быть полезным, php, работа

Previous post Next post
Up