113 lines
5.1 KiB
Markdown
113 lines
5.1 KiB
Markdown
# Квантификаторы +, * и ?
|
||
|
||
Для самые часто востребованных квантификаторов есть специальные короткие обозначения.
|
||
|
||
[cut]
|
||
<dl>
|
||
<dt>`+`</dt>
|
||
<dd>Означает "один или более", то же что `{1,}`.
|
||
|
||
Например, <code class="pattern">\d+</code> находит числа -- последовательности из 1 или более цифр:
|
||
|
||
```js
|
||
//+ run
|
||
var str = "+7(903)-123-45-67";
|
||
|
||
alert( str.match( /\d+/g ) ); // 7,903,123,45,67
|
||
```
|
||
|
||
</dd>
|
||
<dt>`?`</dt>
|
||
<dd>Означает "ноль или один", то же что и `{0,1}`. По сути, делает символ необязательным.
|
||
|
||
Например, <code class="pattern">ou?r</code> найдёт <code class="match">or</code> в слове <code class="subject">color</code> и <code class="match">our</code> в его британском варианте написания <code class="subject">colour</code>.
|
||
|
||
```js
|
||
//+ run
|
||
var str = "Можно писать color или colour";
|
||
|
||
alert( str.match( /colou?r/g ) ); // color, colour
|
||
```
|
||
|
||
</dd>
|
||
<dt>`*`</dt>
|
||
<dd>Означает "ноль или более", то же что `{0,}`. То есть, символ может повторяться много раз или вообще отсутствовать.
|
||
|
||
Пример ниже находит цифру, после которой идёт один или более нулей:
|
||
|
||
```js
|
||
//+ run
|
||
alert( "100 10 1".match( /\d0*/g ) ); // 100, 10, 1
|
||
```
|
||
|
||
Сравните это с `'+'` (один или более):
|
||
|
||
```js
|
||
//+ run
|
||
alert( "100 10 1".match( /\d0+/g ) ); // 100, 10
|
||
```
|
||
|
||
</dd>
|
||
</dl>
|
||
|
||
Эти квантификаторы -- одни из важнейших "строительных блоков" для сложных регулярных выражений, поэтому мы рассмотрим ещё примеры.
|
||
|
||
<dl>
|
||
<dt>Десятичная дробь (число с точкой внутри): <code class="pattern">\d+\.\d+</code></dt>
|
||
<dd>
|
||
|
||
```js
|
||
//+ run
|
||
alert( "0 1 12.345 7890".match( /\d+\.\d+/g ) ); // 123.45
|
||
```
|
||
|
||
</dd>
|
||
<dt>Открывающий HTML-тег без атрибутов, такой как `<span>` или `<p>`: <code class="pattern">/<[a-z]+>/i</code></dt>
|
||
<dd>Пример:
|
||
|
||
```js
|
||
//+ run
|
||
alert( "<BODY> ... </BODY>".match ( /<[a-z]+>/gi ) ); // <BODY>
|
||
```
|
||
|
||
Это регулярное выражение ищет символ <code class="pattern">'<'</code>, за которым идут одна или более букв английского алфавита, и затем <code class="pattern">'>'</code>.
|
||
</dd>
|
||
<dt>Открывающий HTML-тег без атрибутов (лучше): <code class="pattern">/<[a-z][a-z0-9]*>/i</code></dt>
|
||
<dd>
|
||
Здесь регулярное выражение расширено: в соответствие со стандартом, HTML-тег может иметь символ на любой позиции, кроме первой, например `<h1>`.
|
||
|
||
```js
|
||
//+ run
|
||
alert( "<h1>Привет!</h1>".match( /<[a-z][a-z0-9]*>/gi ) ); // <h1>
|
||
```
|
||
|
||
</dd>
|
||
<dt>Открывающий или закрывающий HTML-тег без атрибутов: <code class="pattern">/<\/?[a-z][a-z0-9]*>/i</code></dt>
|
||
<dd>В предыдущий паттерн добавили необязательный слэш <code class="pattern">/?</code> перед тегом. Его понадобилось заэкранировать, чтобы JavaScript не принял его за конец шаблона.
|
||
|
||
```js
|
||
//+ run
|
||
alert( "<h1>Привет!</h1>".match( /<\/?[a-z][a-z0-9]*>/gi ) ); // <h1>, </h1>
|
||
```
|
||
|
||
</dd>
|
||
</dl>
|
||
|
||
|
||
[smart header="Точнее -- значит сложнее"]
|
||
Здесь мы видим классическую ситуацию, которая повторяется из раза в раз.
|
||
|
||
Чем точнее регулярное выражение, тем оно длиннее и сложнее.
|
||
|
||
Например, для HTML-тегов, скорее всего, подошло бы и более короткое регулярное выражение <code class="pattern"><\w+></code>.
|
||
|
||
Так как класс `\w` означает "любая цифра или английская буква или _`, то под такой шаблон подойдут и не теги, например <code class="match"><_></code>, однако он гораздо проще, чем <code class="pattern"><[a-z][a-z0-9]*></code>.
|
||
|
||
Подойдёт ли нам <code class="pattern"><\w+></code> или нужно использовать именно <code class="pattern"><[a-z][a-z0-9]*></code>?
|
||
|
||
В реальной жизни допустимы оба варианта. Ответ на подобные вопросы зависит от того, насколько реально важна точность и насколько сложно потом будет отфильтровать лишние совпадения (если появятся).
|
||
[/smart]
|
||
|
||
|
||
|
||
|