Насамперед варто зауважити, що будь-який рядок сам по собі є регулярним виразом. Регулярні вирази є реєстрозалежними, тому рядок з маленької літери вже не буде відповідати цьому ж виразу з великої літери.
Регулярні вирази мають спецсимволи, які потрібно екранувати. Ось їх список: . ^ $ * + ? { } [ ] \ | ( ).
Екранування здійснюється звичайним способом - додаванням \ перед спецсимволом.
У JavaScript регулярні вирази реалізовані окремим об'єктом RegExp та інтегровані у методи рядків.
Існує два синтаксиси для створення регулярного вираження.
Довгий» синтаксис:
regexp = new RegExp("шаблон", "прапори");
І короткий синтаксис, що використовує сліші "/":
regexp = /шаблон/; // без прапорів
regexp = /шаблон/gmi; // з прапорами gmi
Сліши /.../ говорять JavaScript про те, що це регулярне вираження. Вони відіграють ту саму роль, що й лапки для позначення рядків.
| Символ | Відповідність |
|---|---|
| [...] | Будь-який із символів, вказаних у дужках |
| [^...] | Будь-який із символів, не вказаних у дужках |
| . | Будь-який символ, окрім перекладу рядка або іншого роздільника Unicode-рядка |
| \w | Будь-який текстовий символ ASCII. Еквівалентно [a-zA-Z0-9_] |
| \W | Будь-який символ, що не є текстовим символом ASCII. Еквівалентно [^a-zA-Z0-9_] |
| \s | Будь-який символ пробілу з набору Unicode |
| \S | Будь-який непробільний символ із набору Unicode. Зверніть увагу, що символи \w і \S - це не те саме |
| \d | Будь-які ASCII-цифри. Еквівалентно [0-9] |
| \D | Будь-який символ, відмінний від ASCII-цифр. Еквівалентно [^0-9] |
| [\b] | Літерал символу «забій» |
Зверніть увагу, що керуючі послідовності спеціальних символів класів можуть бути у квадратних дужках. \s відповідає будь-якому символу пробілу, а \d відповідає будь-якій цифрі, отже, /[\s\d]/ відповідає будь-якому символу або цифрі.
| Символ | Значення |
|---|---|
| {n,m} | Відповідає попередньому шаблону, повтореному не менше n і не більше m разів |
| {n,} | Відповідає попередньому шаблону, повтореному n або більше разів |
| {n} | Відповідає точно n екземплярам попереднього шаблону |
| ? | Відповідає нулю або одному примірнику попереднього шаблону; попередній шаблон є необов'язковим. Еквівалентно {0,1} |
| + | Відповідає одному або більше екземплярам попереднього шаблону. Еквівалентно {1,} |
| * | Відповідає нулю або більше екземплярам попереднього шаблону. Еквівалентно {0,} |
Рядки підтримують чотири методи, що використовують регулярні вирази.
Об'єкти RegExp визначають два методи, що виконують пошук за шаблоном; вони поводяться аналогічно методам класу String, описаним вище.
У наступному прикладі визначається функція, яка виділяє помаранчевим кольором рік у тексті.





Першим параметром цього методу можна передавати не просто рядок, а регулярний вираз. Подивіться різницю:
де_меняем.replace(що міняємо, на що міняємо)
alert( 'bab'.replace('a', '!') ); //виведе 'b!b'
alert( 'bab'.replace(/a/g, '!') ); //виведе 'b!b'
Зверніть увагу на слєші /, в яких стоїть буква 'a'. Ці сліші називаються обмежувачами регулярних виразів.
Обмежувачі потрібні для того, щоб після них писати модифікатори. команди, які змінюють загальні властивості регулярного вираження.
Модифікатор - g - включає режим глобального пошуку і заміни - без нього регулярка шукає лише перший збіг, і з ним - все збіги. Подивіться різницю:
alert( 'aab'.replace(/a/, '!') ); //выведет '!ab'
alert( 'aab'.replace(/a/g', '!') ); //
виведе '!!b'
Є також модифікатор i - він змушує регулювання ігнорувати регістр символів:
alert( 'aAb'.replace(/A/g', '!') ); //виведе 'a!b'
alert( 'aAb'.replace(/A/gi', '!') ); //виведе '!!b'
//У другому випадку ігнорується регістр символів.
У регулярні можна вказувати кілька модифікаторів, їх порядок не має значення.
У регулярних виразах є два типи символів: ті, які позначають самі себе та символи-команди (спеціальні символи).
Літери та цифри позначають самі себе, а ось точка є спеціальним символом і означає 'будь-який символ'. Дивіться приклади:
'xax xaax'.replace(/xax/g, '!'); //поверне '! xaax'
'123 xaax'.replace(/123/g, '!'); //вернет '! xaax'
'x3x xaax'.replace(/x3x/g, '!'); //вернет '! xaax'
//Зверніть увагу, що регістр має значення:
'a3b A3B'.replace(/A3B/g, '!'); //поверне 'a3b !'
Далі подивіться приклади з використанням спецсимволу 'точка':
'xax xsx x&x x-x xaax'.replace(/x.x/g, '!'); //поверне '! ! ! ! xaax'
Оскільки точка - це будь-який символ, то під наше регулювання потраплять усі підстроки за таким шаблоном: літера 'x', потім будь-який символ, потім знову літера 'x'. Перші 4 підрядки потрапили під цей шаблон (це xax xsx x&x x-x) та замінилися на '!', а останній підрядок (xaax) не потрапляє, тому що всередині (між літерами 'x') не один символ - а цілих два.
'xax xabx'.replace(/x..x/g, '!'); //поверне 'xax !'
Оскільки точка - це будь-який символ, а в нашому регулярці йдуть дві точки поспіль, то під наше регулювання потраплять усі підрядки за таким шаблоном: буква 'x', потім два будь-які символи, потім знову літера 'x'. Перший підрядок не потрапив під цей шаблон (оскільки має лише 1 символ між літерами 'x'), а останній підрядок (xabx) - потрапив.
Отже, запам'ятайте: літери та цифри позначають самі себе, а точка замінює будь-який символ.
Бувають ситуації, коли ми хочемо вказати, що символ повторюється задану кількість разів. Якщо ми знаємо точну кількість повторень, можна просто написати його кілька разів - (/aaaa/). Але що робити, якщо ми хочемо сказати таке: 'повторити один чи більше разів'?
Для цього існують оператори (квантифікатори) повторення: плюс '+' (один і більше разів), зірочка '*' (нуль і більше разів) та питання '?' (нуль або один раз, інакше кажучи - може бути, а може не бути).
Дані оператори діють на той символ, який стоїть перед ними.
Подивіться приклади:
'xx xax xaax xaaax xbx'.replace(/xa+x/g, '!'); //поверне 'xx ! ! ! xbx'
У цьому випадку шаблон пошуку виглядає так: літера 'x', літера 'a' один або більше разів, літера 'x'.
'xx xax xaax xaaax xbx'.replace(/xa*x/g, '!'); // Поверне '! ! ! ! xbx'
В даному випадку шаблон пошуку виглядає так: літера 'x', літера 'a' нуль або більше разів, літера 'x'. Інакше можна сказати так: літери 'a' чи ні, чи повторюється один чи більше разів.
Крім очевидного варіанта xax xaax xaaax, під шаблон також потрапляє підрядок 'xx', тому що там немає букви 'a' взагалі (тобто 0 разів).
А 'xbx' не потрапив, тому що там немає букви 'a', але є буква 'b' (її ми не дозволили).
'xx xax xaax xbx'.replace(/xa?x/g, '!'); //поверне '! ! xaax xbx'
В даному випадку шаблон пошуку виглядає так: літера 'x', далі літера 'a' може бути або не бути, потім літера 'x'.
У попередніх прикладах оператори повторення діяли лише один символ, який стояв перед ними. Що робити, якщо ми хочемо вплинути на кілька символів?
Для цього існують дужки, що групують. '(' и ')':
'xabx xababx xaabbx'.replace(/x(ab)+x/g, '!'); //поверне '! ! xaabbx'
В даному випадку шаблон пошуку виглядає так: літера 'x', далі рядок 'ab' один або більше разів, потім літера 'x'.
Тобто: якщо щось стоїть у групуючих дужках і відразу після ')' стоїть оператор повторення - він подіє на все, що стоїть усередині дужок.
Припустимо, що хочемо зробити те щоб спецсимвол позначав сам себе. Наприклад, для того, щоб знайти за таким шаблоном: літера 'a', потім плюс '+', потім літера 'x'. Наступний код працюватиме не так, як хотілося б:
'a+x ax aax aaax'.replace(/a+x/g, '!'); //поверне 'a+x ! ! !''
Автор регулярки хотів, щоб шаблон пошуку виглядав так: літера 'a', потім плюс '+', потім літера 'x'.
А насправді він виглядає так: літера 'a' один або більше разів, потім літера 'x'.
Тому підрядок 'a+x' і не потрапив під шаблон (заважає '+') - а решта потрапила.
Отже, правило: щоб спецсимвол позначав сам себе - його потрібно екранувати за допомогою зворотного слішу. Ось так:
'a+x ax aax aaax'.replace(/a\+x/g, '!'); //поверне 'a+x ! ! !'
Ось тепер шаблон пошуку виглядає так, як треба: літера 'a', потім плюс '+', потім літера 'x'.
'a.x abx azx'.replace(/a\.x/g, '!'); // Поверне '! abx azx'
У цьому прикладі шаблон виглядає так: літера 'a', потім точка '.', потім літера 'x'. Порівняйте з наступним прикладом (забутий зворотний сліш):
'a.x abx azx'.replace(/a.x/g, '!'); // Поверне '! ! !'
Всі підрядки потрапили під шаблон, тому що незаекранована точка позначає будь-який символ.
Якщо ви забудете зворотний сліш для точки (коли вона повинна позначати сама себе) - цього можна навіть не помітити:
'a.x'.replace(/a.x/g, '!'); //поверне '!', як ми хотіли
Візуально працює правильно (оскільки точка позначає будь-який символ, у тому числі і звичайну точку '.'). Але якщо поміняти рядок, в якому відбуваються заміни, ми побачимо нашу помилку:
'a.x abx azx'.replace(/a.x/g, '!'); // Поверне '! ! !', А очікувалося '! abx azx'
Будьте уважні!
Якщо екранувати звичайний символ - нічого страшного не станеться - він все одно позначатиме сам себе.
Часто виникає сумнів, чи цей символ є спеціальним. Деякі доходять до того, що екранують усі підозрілі символи поспіль. Однак, це погана практика (захаращує регулювання зворотними слішами).
Є спецсимволами: $ ^ . * +? \{}[]() |
Не є спецсимволами: @ : , ' '' ; - _ = < > % # ~ `&! /
Щоб зрозуміти, про що йтиметься - подивіться приклад:
//Виведе '! e', а чекалося '! qw x e':
'a23e4x qw x e'.replace(/a.+x/g, '!');
У цьому прикладі шаблон пошуку виглядає так: літера 'a', потім будь-який символ один або більше разів, потім літера 'x'.
Проте, регулярка спрацювала не так, як очікував автор - вона захопила максимально можливу кількість символів, тобто закінчилася не на першому іксі 'x', а на останньому 'x'.
Така поведінка операторів (квантифікаторів) повторення називається жадібністю - вони прагнуть забрати якнайбільше.
Така особливість не завжди корисна і, на щастя, її можна скасувати, говорячи інакше - обмежити жадібність.
Це робиться за допомогою додавання знака '?' до оператора повторення: замість жадібних '+' та '*' ми напишемо '+?' і '*?' - вони будуть не такі жадібні:
'a23e4x qw x e'.replace(/a.+?x/g, '!'); поверне '! qw x e'
У цьому прикладі шаблон пошуку виглядає так: літера 'a', потім будь-який символ один або більше разів (з обмеженням жадібності), потім літера 'x'.
За допомогою '?' ми обмежили жадібність плюсу - і тепер він шукає до першого збігу.
Жадібність можна обмежувати всім операторам повторення, у тому числі і '?', і '{}' - ось так: '??' і '{}? '.