Припустимо, у нас є рядок +38(067)-123-45-67
і нам потрібно знайти всі числа в ньому. Але цього разу, на відміну від попередніх, нас цікавлять не поодинокі цифри, а саме числа : 38, 067, 123, 45, 67
.
Число це послідовність з 1, або більше цифр \d
і щоб позначити потрібну нам кількість, ми можемо застосувати квантифікатор.
Кількість {n}
Найпростішим квантифікатором є число у фігурних дужках: {n}
.
Квантифікатор додається до символу(або класу символів, набору [...]
, тощо) і позначає яка їх кількість нам потрібна.
Існує декілька способів використання квантифікатора, розглянемо на прикладах:
- Точна кількість:
{5}
-
\d{5}
означає точно 5 цифр, так само як і\d\d\d\d\d
.Нижченаведений приклад шукатиме число, яке складається з 5-ти цифр:
alert( "Мені 12345 років".match(/\d{5}/) ); // "12345"
Ми могли б додати
\b
і таким чином вилучити з пошуку числа довші за наш шаблон:\b\d{5}\b
. - Діапазон:
{3,5}
, від 3 до 5 -
Щоб знайти числа, які складаються з мінімум 3 і максимум 5 чисел, ми можемо вказати потрібні обмеження у фігурних дужках:
\d{3,5}
alert( "Мені не 12 років, а 1234".match(/\d{3,5}/) ); // "1234"
Ми можемо не вказувати верхню межу.
В такому випадку, регулярний вираз
\d{3,}
шукатиме послідовність цифр довжиною від3
і/або більше:alert( "Мені не 12, а 345678 років".match(/\d{3,}/) ); // "345678"
Давайте повернемось до рядка +38(067)-123-45-67
.
Число це послідовність з однієї або більше цифр підряд. Таким чином, регулярний вираз виглядатиме \d{1,}
:
let str = "+38(067)-123-45-67";
let numbers = str.match(/\d{1,}/g);
alert(numbers); // 38,067,123,45,67
Скорочення
Існують способи скорочено записати більшу частину часто вживаних квантифікаторів:
+
-
Означає “один, або більше”, так само як і
{1,}
.До прикладу,
\d+
шукає числа, які складаються з однієї, або більше цифр:let str = "+38(067)-123-45-67"; alert( str.match(/\d+/g) ); // 38,067,123,45,67
?
-
Означає “нуль, або один”, так само як і
{0,1}
. Інакше кажучи, в такий спосіб ми робимо символ необов’язковим.До прикладу, шаблон
ou?r
шукатиме літеруo
після якої, можливо, йтиме літераu
, і потім літераr
.І таким чином,
colou?r
знайде обидва словаcolor
таcolour
:let str = "Англійською слово колір пишеться як color чи colour?"; alert( str.match(/colou?r/g) ); // color, colour
*
-
Означає “нуль, або більше”, так само, як і
{0,}
. Це означає, що символ може бути відсутнім, або повторюватись безліч разів.До прикладу,
\d0*
шукає цифру, після якої йде будь-яка кількість нулів (може бути багато, або жодного):alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1
Порівняйте з
+
(один, або більше):alert( "100 10 1".match(/\d0+/g) ); // 100, 10 // Регулярний вираз не знайшов 1, оскільки 0+ вимагає наявності щонайменше одного нуля
Більше прикладів
Квантифікатори використовуються дуже часто. Вони основні “будівельні блоки” складних регулярних виразів, тож розглянемо ще декілька прикладів.
Регулярний вираз для десяткових дробів (чисел з плаваючою комою): \d+\.\d+
В дії:
alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345
Регулярний вираз для “відкриваючого HTML-тегу без атрибутів”, наприклад, <span>
, або <p>
.
-
Найпростіший варіант:
/<[a-z]+>/i
alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>
Регулярний вираз шукає символ
'<'
після якого йдуть одна, або більше літер латиницею, а потім'>'
. -
Покращений варіант:
/<[a-z][a-z0-9]*>/i
Згідно стандарту, назва HTML-тегу може містити в собі і цифру на будь-якій позиції окрім першої, як наприклад
<h1>
.alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>
Регулярний вираз “відкриваючого, або закриваючого HTML-тегу без атрибутів”: /<\/?[a-z][a-z0-9]*>/i
Ми додали необов’язковий слеш /?
на початку шаблону і для того, щоб JavaScript не сприйняв його як кінець регулярного виразу, нам довелось його екранувати.
alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
На прикладах ми побачили, що більш точним є регулярний вираз, тим довшим і складнішим є його реалізація.
До прикладу, для HTML-тегів без атрибутів ми могли б використати простіший регулярний вираз: <\w+>
. Але так як HTML має більш жорсткі вимоги до назв тегів, то шаблон <[a-z][a-z0-9]*>
буде більш точним.
Чи можемо ми використовувати <\w+>
чи краще писати <[a-z][a-z0-9]*>
?
В реальному життя обидва варіанти мають право на існування. Все залежить від того, чи готові ми допустити “зайві” співпадіння з нашим регулярний виразом і наскілльки важко, або легко буде відфільтрувати їх і отримати перелік потрібних нам співпадінь.
Коментарі
<code>
, для кількох рядків – обгорніть їх тегом<pre>
, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)