# Квантификаторы +, *, ? и {n} Рассмотрим ту же задачу, что и ранее -- взять телефон вида `+7(903)-123-45-67` и найти все числа в нём. Но теперь нас интересуют не цифры по отдельности, а именно числа, то есть результат вида `7, 903, 123, 45, 67`. Для поиска цифр по отдельности нам было достаточно класса `\d`. Но здесь нужно искать *числа* -- последовательности из 1 или более цифр. ## Количество {n} Количество повторений символа можно указать с помощью числа в фигурных скобках: `{n}`. Такое указание называют *квантификатором* (от англ. quantifier). У него есть несколько подформ записи:
Точное количество: `{5}`
Регэксп \d{5} обозначает ровно 5 цифр, в точности как \d\d\d\d\d. Следующий пример находит пятизначное число. ```js //+ run alert( "Мне 12345 лет".match(/\d{5}/) ); // "12345" ```
Количество от-до: `{3,5}`
Для того, чтобы найти, например, числа размером от трёх до пяти знаков, нужно указать границы в фигурных скобках: \d{3,5} ```js //+ run alert( "Мне не 12, а 1234 года".match(/\d{3,5}/) ); // "1234" ``` Последнее значение можно и не указывать. Тогда выражение \d{3,} найдет числа, длиной от трех цифр: ```js //+ run alert( "Мне не 12, а 345678 лет".match(/\d{3,5}/) ); // "345678" ```
В случае с телефоном нам нужны числа -- одна или более цифр подряд. Этой задаче соответствует регулярное выражение \d{1,}: ```js //+ run var str = "+7(903)-123-45-67"; alert( str.match(/\d{1,}/g) ); // 7,903,123,45,67 ``` ## Короткие обозначения Для самые часто востребованных квантификаторов есть специальные короткие обозначения.
`+`
Означает "один или более", то же что `{1,}`. Например, \d+ находит числа -- последовательности из 1 или более цифр: ```js //+ run var str = "+7(903)-123-45-67"; alert( str.match(/\d+/g) ); // 7,903,123,45,67 ```
`?`
Означает "ноль или один", то же что и `{0,1}`. По сути, делает символ необязательным. Например, регэксп ou?r найдёт o, после которого, возможно, следует u, а затем r. Этот регэксп найдёт or в слове color и our в colour: ```js //+ run var str = "Можно писать color или colour (британский вариант)"; alert( str.match(/colou?r/g) ); // color, colour ```
`*`
Означает "ноль или более", то же что `{0,}`. То есть, символ может повторяться много раз или вообще отсутствовать. Пример ниже находит цифру, после которой идёт один или более нулей: ```js //+ run alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1 ``` Сравните это с `'+'` (один или более): ```js //+ run alert( "100 10 1".match(/\d0+/g) ); // 100, 10 ```
## Ещё примеры Эти квантификаторы принадлежат к числу самых важных "строительных блоков" для сложных регулярных выражений, поэтому мы рассмотрим ещё примеры.
Регэксп "десятичная дробь" (число с точкой внутри): \d+\.\d+
В действии: ```js //+ run alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 123.45 ```
Регэксп "открывающий HTML-тег без атрибутов", такой как `` или `

`: /<[a-z]+>/i

Пример: ```js //+ run alert( " ... ".match(/<[a-z]+>/gi) ); // ``` Это регулярное выражение ищет символ '<', за которым идут одна или более букв английского алфавита, и затем '>'.
Регэксп "открывающий HTML-тег без атрибутов" (лучше): /<[a-z][a-z0-9]*>/i
Здесь регулярное выражение расширено: в соответствие со стандартом, HTML-тег может иметь символ на любой позиции, кроме первой, например `

`. ```js //+ run alert( "

Привет!

".match(/<[a-z][a-z0-9]*>/gi) ); //

```

Регэксп "открывающий или закрывающий HTML-тег без атрибутов": /<\/?[a-z][a-z0-9]*>/i
В предыдущий паттерн добавили необязательный слэш /? перед тегом. Его понадобилось заэкранировать, чтобы JavaScript не принял его за конец шаблона. ```js //+ run alert( "

Привет!

".match(/<\/?[a-z][a-z0-9]*>/gi) ); //

,

```
[smart header="Точнее -- значит сложнее"] В этих примерах мы видим общее правило, которое повторяется из раза в раз: чем точнее регулярное выражение, тем оно длиннее и сложнее. Например, для HTML-тегов, скорее всего, подошло бы и более короткое регулярное выражение <\w+>. Так как класс `\w` означает "любая цифра или английская буква или `'_'`, то под такой регэксп подойдут и не теги, например <_>. Однако он гораздо проще, чем более точный регэксп <[a-z][a-z0-9]*>. Подойдёт ли нам <\w+> или нужно использовать именно <[a-z][a-z0-9]*>? В реальной жизни допустимы оба варианта. Ответ на подобные вопросы зависит от того, насколько реально важна точность и насколько сложно потом будет отфильтровать лишние совпадения (если появятся). [/smart]