Очень и очень трудно мне далось написание этого урока. Регулярные выражения вообще не самое простое, что есть в программировании, а уж для меня, так тем более. Например, пока я писал его, познакомился с функцией escapeRegExp(), которую хотел применить при доработке под свои нужды класса Mootools для поиска и подсветки текста на странице (аналог обычного поиска в Firefox и некоторых других браузерах, но не все ж умеют пользоваться встроенным поиском браузера…). Так вот там у меня ничего не получилось. Дебаггер ФФ всё твердил, что «escapeRegExp() is not a function» (не является функцией). Я так и не понял, что я делал не правильно. А здесь все получилось (в самом конце урока).
Основы
test()
В своем самом простом выражении, регулярное выражение – это простой текст, который нужно найти в документе. Несмотря на то, что JavaScript уже имеет встроенный объект RegExp, который отвечает за формирование регулярных выражений, со своей собственной функцией test(), но функция test() в Mootools является более дружелюбной её версией, чем яваскриптовская.
Для начала, посмотрим на самый простой пример использования функции test(), в котором будем искать определенный текст, в более объемном тексте.
//Текст или строка, в которой будем искать var string_to_test = "Найти что-нибудь здесь"; //Регулярное выражение, которое будем использовать для поиска var regular_expression = "здесь"; //применяем функцию test(), которая возвращает true или false var result = string_to_test.test(regular_expression); //переменная result имеет значение true
По сути, это такой же результат, если бы использовалась функция contains(). Однако, в то время, как contains() ищет целые слова, test() находит вхождения сочетания символов:
var string_to_match = "слово"; //вернёт false string_to_match.contains('лов') //вернёт true string_to_match.test('лов');
И ещё обращу внимание на то, что регулярное выражение не будет чувствительным к регистру, если этого явно не указать с помощью специального ключа. Потому, поиск по регулярному выражению «слово», в слове «Слово» вернёт false. Пример:
var regex_demo = function(){ //определяем функцию обработки var regex_demo_1 = function(){ //определяем исходный текст var test_string = $('regex_1_value').get('value'); //определяем регулярное выражение var regex_value = $('regex_1_match').get('value'); //производим поиск в исходном тексте var test_result = test_string.test(regex_value); //сообщаем пользователю о текущем положении дел if (test_result){$('regex_1_result').set('html', "Есть совпадение!");} else {$('regex_1_result').set('html', "Нет совпадения");} } }
Обращаю внимание на то, что есть некоторые символы, использовать которые нужно очень осторожно. Если использовать один из нижеуказанных символов в примере ниже, это может привести к непредвиденной ошибке и потому, нужно будет перезагрузить страницу, чтобы все примеры страницы работали.
- . * + ? ^ $ { } ( ) | [ ] / \
| Текст, в котором производим поиск: | |
| Регулярное выражение: | |
|
|
Игнорируем регистр
Существует масса ситуаций, когда нет необходимости, чтобы регулярное выражение было чувствительным к регистру текста. Для того, чтобы это уточнить для функций, работающих с регулярными выражениями, нужно использовать параметр «i», как это указано в следующем примере.
//Строка, в которой будем производить поиск var string_to_test = "ИгнОр РЕгИстрУ"; //вернёт false string_to_test.test("игнор"); //вернёт true string_to_test.test("игнор", "i");
Функции test() можно передать несколько параметров, но, так как JavaScript поддерживает только 3 параметра регулярного выражения (2 из которых включены по умолчанию в функции test()), параметр «i», вероятно, единственный, который нужно будет передавать. Ниже, в форме, можете протестировать функцию test() с параметром игнорирования регистра.
var regex_demo = function(){ //Получить строку для тестирования из поля input var test_string = $('regex_value').get('value'); //Получить регулярное выражение из поля input var regex_value = $('regex_match').get('value'); //Проверить, требуется ли игнорирование регистра var regex_param = ""; if ($('regex_param').checked){ regex_param = "i"; } //Произвести поиск и получить результат var test_result = test_string.test(regex_value, regex_param); //Обновить приготовленный контейнер для сообщения результатов поиска if (test_result){ $('regex_result').set('html', "Есть находка!"); } else { $('regex_result').set('html', "Ничего нет!
"); } }
| Строка, в которой будем искать: | |
| Определим регулярное выражение: | |
| Игнор регистру? | |
|
|
Интересная часть
Итак, мы уже просмотрели примеры простого поиска по регулярным выражениям, можно начать смотреть в сторону более сложных выражений. Охватить всю функциональность и возможности регулярных выражений сейчас не получится (да я и не претендую на это), но ознакомиться то «самое, самое», что можно будет использовать в своих простых приложениях, у нас получится. Даже этого должно будет хватить для решения простых задач (меня регуляри не раз спасали – некоторые до сих пор использую в DreamWeaver-е).
Находим начало строки с помощью оператора «^»
Оператор «^» при использовании в регулярных выражениях, помогает найти текст в начале строки, вне зависимости от того, существует ли этот текст далее в строке поиска. Установите оператор в начале строки для поиска, вот так:
//Строка, в которой будем производить поиск var string_to_test = "поищем в начале текста" //тестирует верхний текст на предмет того, начинается ли он с данной строки //возвращает true var is_true = string_to_test.match("^поищем");
Далее, если выражение не находится в начале текста, этот поиск
вернет, соотвественно, false:
//Строка, в которой будем производить поиск var string_to_test = "поищем в начале текста" //тестирует верхний текст на предмет того, начинается ли он с данной строки //возвращает (удивление) false var is_true = string_to_test.match("^начал");
Эти два примера можно и протестировать здесь:
| Строка, в которой будем искать: | |
| Регулярное выражение: | |
| Регистру игнор? | |
|
|
Поиск по концам с помощью оператора «$»
Этот оператор работает также, как и предыдущий («^»), только с двумя исключениями:
- Поиск только по концу строк
- Устанавливается в конце регулярного выражения
В остальном, регЭкспы с этим оператором работают как и ожидается
:
//Строка, в которой будем искать var string_to_test = "поиск по концам строк"; //проверяет, заканчивается ли строка на слово "строк" //и возвращает "true" var is_true = string_to_test.match("строка$"); //проверяет, заканчивается ли строка на слово "металлика" //и вовращает "false" var is_false = string_to_test.match("металлика$");
Используя оба этих оператора, можно протестировать исходный текст на полное совпадение с регулярным выражением:
//Исходная строка var string_to_test = "проверим на полное совпадение"; //Проверяет на полное совпадение со строкой "проверим на полное совпадение" //возвращает true var is_true = string_to_test.match("^проверим на полное совпадение$"); //Проверяет на полное совпадение со строкой "проверим на полное совпадение" //возвращает false var is_false = string_to_test.match("^проверим на совпадение$");
| Исходная строка: | |
| Регулярное выражение: | |
| Игнор регистру? | |
|
|
Классы символов
Классы символов – это ещё один инструмент регулярных выражений (жутко полезный, нужно заметить), позволяющий производить поиск нескольких определенных символов («А» или «Я», «f» или «r») или символов из определенного диапазона (от «A» до «Z» или от «r» до «z»). Если, например, есть необходимость проверить строку на наличие слов «бее» или «мее», мы заключаем две первые буквы этих слов в [квадратные] скобки, таким образом формируя класс символов и использовать следующее регулярное выражение:
//строка, в которой будем искать слово "мее" var first_string_to_test = "овцы разговаривают словом мее"; //строка, в которой будем искать слово "бее" var second_string_to_test = "козы разговаривают словом бее"; //это выражение найдет совпадение в первой строке, но не во второй var returns_true = first_string_to_test.test("мее"); var returns_false = second_string_to_test.test("мее"); //следующее найдет совпадение во второй строке, но не в первой returns_false = first_string_to_test.test("бее"); returns_true = second_string_to_test.test("бее") //следующее найдет совпадение в обеих строках returns_true = first_string_to_test.test("[мб]ее"); returns_true = second_string_to_test.test("[мб]ее");
| Первая строка, в которой будем искать: |
|
|
| Вторая строка, в которой будем искать: |
|
|
| РегЭксп: | ||
| Игнор регистру? | ||
Для того, чтобы использовать диапазон символов для поиска, нужно лишь указать начальную и окончательную точку диапазона, разделив их дефисом («-»). Так можно определять диапазоны как цифр, так и букв, причем необязательно ограничиваться латинскими: кириллические символы также хорошо понимаются движком регулярных выражений, как и латинские. Хотя, стоит оговориться, что букву «ё» движок регулярных выражений не понимает, хотя, возможно я чего-то не знаю (буду благодарен, если кто-нибудь ткнет меня носом в проблему
) .
//строка, в которой будем искать var string_to_test = " b, д или 3"; //поиск символов a, b, c, или d. Вернёт true. string_to_test.test("[a-d]"); //поиск по символам г, д, е, ж или з. Вернёт true. //Обратите внимание, "ё" в списке нет. "ё" не находится. Почему, пока не знаю... string_to_test.test("[г-з]"); //поиск 1, 2, 3, 4 или 5. Вернёт true. string_to_test.test("[1-5]");
Если необходимо искать несколько классов символов, нужно будет заключить такие классы в свои собственные [квадратные] скобки и разделить их логическим оператором «|» (OR – или). Таким образом, у нас появляется регулярное выражение с использованием вложенных квадратных скобок.
//строка, в которой будем искать var string_to_test = "b, д или 3"; //Вернёт true, так как все три выражения верны. string_to_test.test("[a-d] | [г-з] | [1-5]");
Вот пример, в котором можно немного поиграться с полями: воодите туда любой текст, кликайте по соответствующим кнопка регЭкспа и следите за тем, что возвращает true, а что false. «Да прибудет с тобой сила!»
| Первая строка, в которой будем искать: |
|
|
| Вторая строка, в которой будем искать: |
|
|
| Третья строка, в которой будем искать: |
|
|
| РегЭксп: | ||
| Игнор регистру? | ||
escapeRegExp()
Если ты, о читатель моего поста про регулярные выражения, дочитал до сего момента, и о тебе можно сказать, что ты человек с логическим типом мышления, то ты наверняка заметил, использование многочиленных специальных символов в определении регулярного выражения, например классов символов или его логики (ИЛИ – «|«, в начале строки – «^«, в конце строки – «$» и т.д.). Ты ведь наверняка уже понял, что все эти символы сильно затрудняют поиск самих специальных символов в определенной строке… На первый взгляд. А на второй взгляд, все что нужно сделать, это экранировать специальные символы другим специальным символом – обратный слэш «\«, а если нужно искать сам обратный слэш, то используются два обратных слэша «\\«. Логика проста, если не думатьо ней
!
//Строка для поиска. Обратите внимание на специальные символы [ ] - и $ var string_to_match = "[всякий-разный-текст] или $300"; //Было бы неправильно составить такое регулярное выражение //потому что движок будет их воспринимать, как специальные символы //а нам этого не нужно string_to_match.test("[всякий-разный-текст]"); string_to_match.test("$300"); //Правильно было бы так: //обратите внимание на обратный слэш \ перед символами [ ] - и $ string_to_match.test("\[stuff\-in\-here\]"); string_to_match.test("\$300");
Когда регулярное выражение не большое, не составит особого труда экранировать каждый спец. символ. Но с другой стороны никто не отменял банальной человеческой невнимательности (которая у меня, например, хроническая), и такой специальный символ можно просто упустить из виду, или же, на стадиях своего обучения, можно и не подозревать, что ты пропустил специальный символ, не экранировал его и регЭксп не дает нужного результата. На всякий случай, если запомните сразу, вот специальные, рабочие символы регулярных выражений, которые НУЖНО экранировать:
- . * + ? ^ $ { } ( ) | [ ] / \
К счастью, Mootools – это не та библиотека, которая позволит своему пользователю бездарно убивать время на экранирование каждого рабочего символа, когда есть такая функция, как escapeRegExp(), чья работа – это избавить тебя, о начинающий программист, от экранирования специальных символов в регулярном выражении. Эта функция работает с любой строкой, потому ее можно использовать всегда, когда нужно произвести поиск какого-либо текста.
//Нужно экранировать var unescaped_regex_string = "[текст-регулярного-выражения]"; //Экранируем строку var escaped_regex_string = unescaped_regex_string.escapeRegExp(); //escaped_regex_string стала такой: "\[текст\-регулярного\-выражения\]"
Обратите внимание, что это значит, что любой специальный символ, который нужно использовать в регулярном выражении, нужно добавить к регулярному выражению после использования функции escapeRegExp():
//Строка, которую нужно экранировать var unescaped_regex_string = "[текст-регулярного-выражения]"; //Экранировать строку, для поиска по началу строки var escaped_regex_string = "^" + unescaped_regex_string.escapeRegExp(); //переменная escaped_regex_string стала такой: "^\[текст\-регулярного\-выражения\]"
Ниже представлен пример, в котором видна разница между использованием и неиспользованием функции escapeRegExp():
var regex_demo = function(){ //Получаем строку для проверки var test_string = $('regex_7_value').get('value'); //Получаем регулярное выражение var regex_value = $('regex_7_match').get('value'); //Проверяем, нужно ли экранировать текст if ($('regex_7_escape').checked){ //Если да, применяем соотв. функцию regex_value = regex_value.escapeRegExp(); } //Определяем параметры регулярного выражения var regex_param = ""; //Проверяет, нужно ли игнорировать регистр if ($('regex_7_param').checked){ regex_param = "i"; } //Запуск теста var test_result = test_string_1.test(regex_value, regex_param); if (test_result){$('regex_7_result').set('html', "Есть совпадения");} else {$('regex_7_result').set('html', "Нет совпадений!");} }
| Строка, в которой будем производить поиск: | |
| Регялурное выражение: | |
| использовать escapeRegExp(): | |
| Игнор регистру: | |
|
|
Помните, что все примеры можно «сломать», если использовать неэкранированные специальные символы. Потому, если вдруг случается, что что-то перестало работать, после того, как только что это работало – не удивляйтесь, а просто перезагрузите страницу
.
Если все пойдет по плану, то у меня на готовке еще несколь интересных материалов и уроков, потому не забудьте подписаться на мою RSS ленту.

#1 by Владимир on 17.04.2011 - 3:06 pm
Спасибо. Хорошая статья, мне понравилось. Особенно наличия
“примеров”. Вот только нет информации по проверке строк на
соответствие определенным правилам, например как при проверке
E-mail. А так 5 баллов