Розглянемо практичне завдання – у нас є номер телефону типу "+1(703)-123-45-67", і нам потрібно перетворити його на рядок тільки з чисел: 17031234567.
Для цього ми можемо знайти та видалити все, що не є числом. Із цим нам допоможуть символьні класи.
Символьний клас – це спеціальне позначення, яке відповідає будь-якому символу з певного набору.
Для початку давайте розглянемо клас “цифра”. Він позначається як \d і відповідає “будь-якій одній цифрі”.
Наприклад, знайдемо першу цифру в номері телефону:
let str = "+1(703)-123-45-67";
let regexp = /\d/;
alert( str.match(regexp) ); // 1
Без прапорця g регулярний вираз шукає лише перший збіг, тобто першу цифру \d.
Давайте додамо прапорець g, щоб знайти всі цифри:
let str = "+1(703)-123-45-67";
let regexp = /\d/g;
alert( str.match(regexp) ); // масив збігів: 1,7,0,3,1,2,3,4,5,6,7
// давайте зробимо з них номер телефону лише з цифр:
alert( str.match(regexp).join('') ); // 17031234567
Це був символьний клас для цифр. Є й інші символьні класи.
Найбільш використовувані:
\d(“d” від англійского “digit” означає “цифра”)- Цифра: символ від
0до9. \s(“s” від англійского “space” означає “пробіл”)- Пробільні символи: включає символ пробілу, табуляції
\t, перенесення рядка\nі деякі інші рідкісні пробілові символи, що позначаються як\v,\fі\r. \w(“w” від англійского “word” означає “слово”)- Символ “слова” – літера латинського алфавіту, цифра або символ підкреслення
_. Нелатинські літери (наприклад, кирилиця чи хінді) не належать до\w.
Наприклад, \d\s\w означає “цифру”, за якою йде “символ пробілу”, після якого йде “символ слова”, наприклад 1 a.
Регулярний вираз може містити як звичайні символи, так і символьні класи.
Наприклад, CSS\d відповідає рядку CSS із цифрою після нього:
let str = "Чи існує CSS4?";
let regexp = /CSS\d/
alert( str.match(regexp) ); // CSS4
Також ми можемо використовувати багато символьних класів:
alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5'
Відповідність (кожному символьному класу відповідає один символ результату):
Зворотні символьні класи
Для кожного символьного класу існує “зворотній клас”, що позначається тією ж літерою, але у верхньому регістрі.
“Зворотній” означає, що він відповідає всім іншим символам, наприклад:
\D- Не цифра: будь-який символ, окрім
\d, наприклад, літера. \S- Не пробіл: будь-який символ, окрім
\s, наприклад, літера. \W- Будь-який символ, окрім
\w, тобто не букви з латиниці, не символ підкреслення і цифра.
На початку розділу ми бачили, як створити номер телефону з рядка виду +1(703)-123-45-67: знайти всі цифри та з’єднати їх.
let str = "+1(703)-123-45-67";
alert( str.match(/\d/g).join('') ); // 17031234567
Альтернативний, коротший шлях – знайти нецифрові символи \D і видалити їх з рядка:
let str = "+1(703)-123-45-67";
alert( str.replace(/\D/g, "") ); // 17031234567
Крапка – це будь-який символ
Крапка . – це спеціальний символьний клас, який відповідає “будь-якому символу, крім символу нового рядка”.
Наприклад:
alert( "Y".match(/./) ); // Y
Або в середині регулярного виразу:
let regexp = /CS.4/;
alert( "CSS4".match(regexp) ); // CSS4
alert( "CS-4".match(regexp) ); // CS-4
alert( "CS 4".match(regexp) ); // CS 4 (пробіл також є символом)
Зверніть увагу, що точка означає “будь-який символ”, але не “відсутність символу”. Там має бути будь-який символ, щоб відповідати умові пошуку:
alert( "CS4".match(/CS.4/) ); // null, немає збігів тому що немає символу для точки
Крапка, як буквально будь-який символ із прапорцем “s”.
Типово крапка не відповідає символу нового рядка \n.
Наприклад, регулярний вираз A.B відповідає A, а потім B з будь-яким символом між ними, крім символу нового рядка \n:
alert( "A\nB".match(/A.B/) ); // null (немає збігів)
Є багато ситуацій, коли ми хотіли б, щоб крапка означала буквально “будь-який символ”, включаючи новий рядок.
Ось що робить прапорець s. Якщо регулярний вираз містить його, то крапка . відповідає буквально будь-якому символу:
alert( "A\nB".match(/A.B/s) ); // A\nB (збіг!)
Прапорець s не підтримується в IE.
На щастя, є альтернатива, яка працює всюди. Ми можемо використовувати регулярний вираз, як-от [\s\S], щоб знаходити “будь-який символ” (цей шаблон буде описано в статті Набори та діапазони [...]).
alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (збіг!)
Шаблон [\s\S] буквально говорить: “пробіл АБО не пробіл”. Іншими словами, “що завгодно”. Ми могли б використати іншу пару додаткових класів, наприклад [\d\D], це не має значення. Або навіть [^] – оскільки це означає збіг будь-якого символу, крім нічого.
Також ми можемо використати цей прийом, якщо хочемо, щоб обидва типи “крапок” були в одному шаблоні: наявний шаблон . крапки, який поводиться звичайним чином (“без нового рядка”), а також відповідності “будь-якому символу” з [\s\S] або подібним.
Зазвичай ми приділяємо мало уваги пробілам. Для нас рядки 1-5 і 1 - 5 майже ідентичні.
Але якщо регулярний вираз не враховує пробіли, він може не спрацювати.
Спробуємо знайти цифри, розділені дефісом:
alert( "1 - 5".match(/\d-\d/) ); // null, немає збігів!
Давайте виправимо це, додавши пробіли в регулярний вираз \d - \d:
alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, тепер працює
// або ми можемо використати \s клас:
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, також працює
Пробіл – це символ. Так само важливий, як і будь-який інший.
Ми не можемо додавати або видаляти пробіли в регулярному виразі й сподіватися, що він працюватиме так само.
Іншими словами, у регулярному виразі всі символи мають значення, пробіли також.
Підсумки
Існують такі класи символів:
\d– цифри.\D– нецифри.\s– символи пробілів, табуляції, символи нового рядка.\S– усі символи, крім\s.\w– латинські літери, цифри, підкреслення'_'.\W– усі символи, крім\w..– будь-який символ, якщо використовується з прапорцем регулярного виразу's', інакше будь-який символ, крім символу нового рядка\n.
…Але це ще не все!
Кодування Юнікод, яке використовується JavaScript для рядків, надає багато властивостей для символів, наприклад: до якої мови належить літера (якщо це літера), чи це знак пунктуації тощо.
Ми також можемо шукати за цими властивостями. Для цього потрібен прапорець u, який описано в наступній статті.
Коментарі
<code>, для кількох рядків – обгорніть їх тегом<pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)