Декільки символів, або класи символів всередині квадратних дужок […] означають “шукати будь-який символ з-поміж заданих”.
Набори
До прикладу, [eao] означає будь-який з трьох символів: 'a', 'e', or 'o'.
У такий спосіб записується так званий набір. Набір може використовуватись в регулярних виразах разом зі звичайними символами:
// знайти [t або m], а потім "op"
alert( "Mop top".match(/[tm]op/gi) ); // "Mop", "top"Зверніть увагу, що незважаючи на те, що в наборі вказано два символи, в результаті є співпадіння лише по одному з них.
Тож нижченаведений приклад не знайде співпадінь:
// знайти "V", потім [o чи i], потім "la"
alert( "Voila".match(/V[oi]la/) ); // null, співпадінь не знайденоШаблон шукає:
- V,
- потім одна з літер набору [oi],
- потім la.
Результатом такого пошуку могли б стати варіанти Vola або Vila.
Діапазони
Квадратні дужки також можуть містити діапазони символів.
До прикладу, [a-z] шукатиме символу в діапазоні від a до z, а [0-5] дорівнює цифрам в діапазоні від 0 до 5.
В нижченаведеному прикладі ми шукатимемо літеру "x" за якою ідуть дві цифри, або літери від A до F:
alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) ); // xAFТут [0-9A-F] має в собі одразу два діапазони: він шукає символ, який є або цифрою від 0 до 9, або літерою від A до F.
Якби ми захотіли шукати літери не тільки верхнього, а й нижнього регістру, ми могли б додати діапазон a-f: [0-9A-Fa-f]. Або додати флаг i.
Крім того, всередині […] ми можемо використовувати символьні класи.
До прикладу, якщо ми захочемо знайти символ “слова” \w , або дефіс -, набір виглядатиме наступним чином [\w-].
Комбінувати декілька класів теж можливо, наприклад [\s\d] означає “пробіл, або цифра”.
До прикладу:
- \d – те саме, що й [0-9],
- \w – те саме, що й [a-zA-Z0-9_],
- \s – те саме, що й [\t\n\v\f\r ], плюс декілька інших рідкісних пробільних символів Unicode.
Приклад: \w в інших мовах світу
Оскільки символьний клас \w це лише скорочений запис [a-zA-Z0-9_], він не зможе знайти китайські ієрогліфи, літери кирилицею тощо.
Існує спосіб написати більш універсальний шаблон, що включатиме в себе буквенні символи будь-якої мови світу. Це легко реалізувати завдяки властивостям Unicode: [\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}].
Давайте розшифруємо цей шаблон. Подібно до \w, ми створюємо свій діапазон, який включає в себе символи з наступними властивостями Unicode:
- Alphabetic(- Alpha) – для літер,
- Mark(- M) – для акцентів,
- Decimal_Number(- Nd) – для цифр,
- Connector_Punctuation(- Pc) – для нижнього підкреслення- '_'і подібних символів,
- Join_Control(- Join_C) – два спеціальних коди- 200cта- 200d, які використовуються у лігатурах, зокрема в арабській мові.
Шаблон в дії:
let regexp = /[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]/gu;
let str = `Hi 你好 12`;
// знайти всі літери та цифри:
alert( str.match(regexp) ); // H,i,你,好,1,2Звичайно, ми можемо редагувати вищенаведений шаблон: додавати Unicode властивості, або видаляти їх. Дізнатись більше про Unicode властивості можна за посиланням Юнікод: прапорець "u" та клас \p{...}.
Unicode властивості p{…} недоступні у Internet Explorer. Втім, якщо вони нам все ж потрібні, ми можемо скористатись бібліотекою XRegExp.
Або просто вказати діапазон потрібних нам символів з необхідної мови, наприклад [а-я] для літер кирилицею.
Діапазони виключень
Окрім звичайних діапазонів, існують діапазони “виключень” які виглядають наступним чином: [^…].
Вони відрізняються символом каретки ^ на початку і знаходять будь-який символ окрім вказаних в діапазоні.
До прикладу:
- [^aeyo]– будь-який символ окрім- 'a',- 'e',- 'y'or- 'o'.
- [^0-9]– будь-який символ окрім цифр, так само як і- \D.
- [^\s]– будь-який не пробільний символ- \S.
Нижченаведений приклад шукає будь-який символ окрім літер латиницею, цифр та пробільних символів:
alert( "alice15@gmail.com".match(/[^\d\sA-Z]/gi) ); // @ та .Екранування всередині […]
Зазвичай, коли ми хочемо знайти один зі спецсимволів, нам потрібно екранувати його наступним чином \.. Тобто, якщо нам потрібна зворотня коса риска, ми маємо писати \\, і  так далі.
В квадратних дужках ми можемо використовувати велику кількість спецсимволів без екранування:
- Символ . + ( )не потребує екранування.
- Дефіс -не потребує екранування на початку, або в кінці (тобто коли не може означати діапазон).
- Каретка ^екранується лише на початку (без екранування означає набір символів-виключень).
- Закриваюча квадратна дужка ]завжди потребує екранування (у випадках, коли нам потрібно знайти цей символ).
Інакше кажучи, всі спецсимволи можна використовувати без екранування тоді, коли вони не мають додаткового значення в квадратних дужках.
Крапка . всередині квадратних дужок означає просто крапку. Шаблон [.,] шукатиме один з двох символів, або крапку, або кому.
В нижченаведеному прикладі регулярний вираз [-().^+] шукає один з вказаних символів -().^+:
// Не потрібно екранувати
let regexp = /[-().^+]/g;
alert( "1 + 2 - 3".match(regexp) ); // Знаходить +, -…Але якщо ви вирішите все ж таки екранувати їх, “про всяк випадок”, гірше від того не буде:
// Всі символи екрановані
let regexp = /[\-\(\)\.\^\+]/g;
alert( "1 + 2 - 3".match(regexp) ); // так само находить: +, -Діапазони і прапорець “u”
Якщо в діапазоні є сурогатні пари, для коректної роботи регулярного виразу, прапорець u є обов’язковим.
До прикладу, давайте знайдемо [𝒳𝒴] у рядку 𝒳:
alert( '𝒳'.match(/[𝒳𝒴]/) ); // виводить дивний символ, схожий на [?]
// (пошук було виконано некореткно, повернуто тільки половину символу)Результат є некоректним, оскільки типово регулярні вирази “не знають” про сурогатні пари.
Регулярний вираз сприймає [𝒳𝒴] – не як два, а як чотири символи:
- ліва половина 𝒳(1),
- права половина 𝒳(2),
- ліва половина 𝒴(3),
- права половина 𝒴(4).
Якщо вивести їх кодове значення ми побачимо наступне:
for(let i=0; i<'𝒳𝒴'.length; i++) {
  alert('𝒳𝒴'.charCodeAt(i)); // 55349, 56499, 55349, 56500
};Отже, вищенаведений приклад знайшов і вивів ліву половину 𝒳.
Якщо ми додамо прапорець u, то поведінка буде коректною:
alert( '𝒳'.match(/[𝒳𝒴]/u) ); // 𝒳Подібна ситуація складається коли ми шукаємо в діапазоні, наприклад [𝒳-𝒴].
Якщо ми забудемо додати прапорець u, то отримаємо помилку:
'𝒳'.match(/[𝒳-𝒴]/); // Error: Invalid regular expressionПричина в тому, що без прапорцю u сурогатні пари сприймаються як два окремих символи, тобто [𝒳-𝒴] обробляються як [<55349><56499>-<55349><56500>] (кожна сурогатна пара замінюється на набір кодів). Таким чином, ми бачимо, що діапазон 56499-55349 є некоректним: його початковий номер 56499 більший за останній 55349. Це і є причиною помилки.
З прапорцем u шаблон працює коректно:
// шукає символи від 𝒳 до 𝒵
alert( '𝒴'.match(/[𝒳-𝒵]/u) ); // 𝒴
Коментарі
<code>, для кількох рядків – обгорніть їх тегом<pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)