renovation
|
@ -53,7 +53,7 @@ alert( str.indexOf(substr) ); // 2
|
|||
Но это соответствие лишь кажущееся. Очень скоро мы усложним регулярные выражения, и тогда увидим, что они гораздо мощнее.
|
||||
|
||||
[smart header="Цветовые обозначения"]
|
||||
Здесь и далее используется следующая цветовая схема:
|
||||
Здесь и далее в тексте используется следующая цветовая схема:
|
||||
<ul>
|
||||
<li>регэксп (регулярное выражение) - <code class="pattern">красный</code></li>
|
||||
<li>строка - <code class="subject">синий</code></li>
|
||||
|
@ -76,7 +76,7 @@ alert( str.indexOf(substr) ); // 2
|
|||
<dd>Многострочный режим.</dd>
|
||||
</dl>
|
||||
|
||||
Самый очевидный из этих флагов -- безусловно, `i`.
|
||||
Самый простой для понимания из этих флагов -- безусловно, `i`.
|
||||
|
||||
Пример его использования:
|
||||
|
||||
|
@ -89,18 +89,16 @@ alert( str.search( *!*/ЛЮ/i*/!* ) ); // 2
|
|||
```
|
||||
|
||||
<ol>
|
||||
<li>С регом `/ЛЮ/` вызов вернул `-1`, что означает "не найдено" (то же соглашение, что и `indexOf`),</li>
|
||||
<li>С регом `/ЛЮ/i` вызов нашёл совпадение на позиции 2, так как стоит флаг `i`, а значит "лю" тоже подходит.</li>
|
||||
<li>С регом <code class="pattern">/ЛЮ/</code> вызов вернул `-1`, что означает "не найдено" (как и в `indexOf`),</li>
|
||||
<li>С регом <code class="pattern">/ЛЮ/i</code> вызов нашёл совпадение на позиции 2, так как стоит флаг `i`, а значит "лю" тоже подходит.</li>
|
||||
</ol>
|
||||
|
||||
Следующий, пожалуй, самый важный флаг -- это `g`.
|
||||
|
||||
Мы рассмотрим его в следующей секции, вместе с основными методами поиска по регулярным выражениям в JavaScript.
|
||||
Другие флаги мы рассмотрим в последующих главах.
|
||||
|
||||
## Итого
|
||||
|
||||
<ul>
|
||||
<li>Регулярное выражение состоит из шаблона и необязательных флагов `g`, `i` и `m`.</li>
|
||||
<li>Поиск по регулярному выражению <code class="pattern">/регэксп/</code> без флагов и спец. символов, которые мы изучим далее -- это то же самое, что и обычный поиск подстроки в строке.</li>
|
||||
<li>Поиск по регулярному выражению без флагов и спец. символов, которые мы изучим далее -- это то же самое, что и обычный поиск подстроки в строке. Но флаги и спец. символы, как мы увидим далее, могут сделать его гораздо мощнее.</li>
|
||||
<li>Метод строки `str.search(regexp)` возвращает индекс, на котором найдено совпадение.</li>
|
||||
</ul>
|
||||
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
@ -1,14 +1,14 @@
|
|||
# Методы RegExp и String
|
||||
|
||||
В JavaScript методы для работы с регулярными выражениями есть в классе `RegExp`, а также встроены в обычные строки `String`
|
||||
Регулярные выражения в JavaScript являются объектами класса [RegExp](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/RegExp).
|
||||
|
||||
Всего этих методов немного, поэтому мы сначала рассмотрим их по отдельности, а затем -- рецепты по решению стандартных задач с ними.
|
||||
Кроме того, методы для поиска по регулярным выражениям встроены прямо в обычные строки `String`.
|
||||
|
||||
К сожалению, общая структура встроенных методов слегка запутана, поэтому мы сначала рассмотрим их по отдельности, а затем -- рецепты по решению стандартных задач с ними.
|
||||
|
||||
[cut]
|
||||
|
||||
## Методы строк
|
||||
|
||||
### str.search(regexp)
|
||||
## str.search(regexp)
|
||||
|
||||
Этот метод мы уже видели.
|
||||
|
||||
|
@ -25,7 +25,7 @@ alert( str.search( *!*/лю/i*/!* ) ); // 0
|
|||
|
||||
Нельзя заставить `search` искать дальше первого совпадения, такой синтаксис попросту не предусмотрен. Но есть другие методы, которые это умеют.
|
||||
|
||||
### str.match(regexp) без флага g, скобочные выражения
|
||||
## str.match(regexp) без флага g
|
||||
|
||||
Метод `str.match` работает по-разному, в зависимости от наличия или отсутствия флага `g`, поэтому сначала мы разберём вариант, когда его нет.
|
||||
|
||||
|
@ -43,7 +43,7 @@ var result = str.match( *!*/ой/i*/!* );
|
|||
|
||||
alert( result[0] ); // ОЙ (совпадение)
|
||||
alert( result.index ); // 0 (позиция)
|
||||
alert( result.input ); // ОЙ-Ой-ой (поисковая строка)
|
||||
alert( result.input ); // ОЙ-Ой-ой (вся поисковая строка)
|
||||
```
|
||||
|
||||
У этого массива не всегда только один элемент.
|
||||
|
@ -60,12 +60,15 @@ var result = str.match( *!*/JAVA(SCRIPT)/i*/!* );
|
|||
|
||||
alert( result[0] ); // javascript (всё совпадение полностью)
|
||||
alert( result[1] ); // script (часть совпадения, соответствующая скобкам)
|
||||
// также есть свойства result.index, result.input
|
||||
alert( result.index ); // 0
|
||||
alert( result.input ); // javascript - это такой язык
|
||||
```
|
||||
|
||||
Благодаря флагу `i` поиск не обращает внимание на регистр буквы, поэтому находит <code class="match">javascript</code>. При этом часть строки, соответствующая <code class="pattern">SCRIPT</code>, выделена в отдельный элемент массива. Позже мы используем это для поиска с заменой.
|
||||
Благодаря флагу `i` поиск не обращает внимание на регистр буквы, поэтому находит <code class="match">javascript</code>. При этом часть строки, соответствующая <code class="pattern">SCRIPT</code>, выделена в отдельный элемент массива.
|
||||
|
||||
### str.match(regexp) с флагом g
|
||||
Позже мы ещё вернёмся к скобочным выражениям, они особенно удобны для поиска с заменой.
|
||||
|
||||
## str.match(regexp) с флагом g
|
||||
|
||||
При наличии флага `g`, вызов `match` возвращает обычный массив из всех совпадений.
|
||||
|
||||
|
@ -97,8 +100,7 @@ alert( result.index ); // undefined
|
|||
|
||||
Из последнего примера видно, что элемент в массиве ровно один, и свойства `index` также нет. Такова особенность глобального поиска при помощи `match` -- он просто возвращает все совпадения.
|
||||
|
||||
Для расширенного глобального поиска, который позволит получить все позиции и, при желании, скобки, нужно использовать метод [:RegExp#exec], которые будет рассмотрен далее.
|
||||
|
||||
Для расширенного глобального поиска, который позволит получить все позиции и, при желании, скобки, нужно использовать метод [RegExp#exec](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec), которые будет рассмотрен далее.
|
||||
|
||||
[warn header="В случае, если совпадений не было, `match` возвращает `null`"]
|
||||
Обратите внимание, это важно -- если `match` не нашёл совпадений, он возвращает не пустой массив, а именно `null`.
|
||||
|
@ -109,12 +111,12 @@ alert( result.index ); // undefined
|
|||
//+ run
|
||||
var str = "Ой-йой-йой";
|
||||
|
||||
// результат match не всегда массив!
|
||||
alert( str.match( /лю/gi ).length ) // ошибка! нет свойства length у null
|
||||
```
|
||||
|
||||
[/warn]
|
||||
|
||||
### str.split(regexp|substr, limit)
|
||||
## str.split(regexp|substr, limit)
|
||||
|
||||
Разбивает строку в массив по разделителю -- регулярному выражению `regexp` или подстроке `substr`.
|
||||
|
||||
|
@ -134,7 +136,7 @@ alert( '12-34-56'.split('-') ) // [12, 34, 56]
|
|||
alert( '12-34-56'.split(/-/) ) // [12, 34, 56]
|
||||
```
|
||||
|
||||
### str.replace(regexp, newSubStr|function)
|
||||
## str.replace(regexp, newStr|function)
|
||||
|
||||
Швейцарский нож для работы со строками, поиска и замены любого уровня сложности.
|
||||
|
||||
|
@ -143,12 +145,12 @@ alert( '12-34-56'.split(/-/) ) // [12, 34, 56]
|
|||
```js
|
||||
//+ run
|
||||
// заменить дефис на двоеточие
|
||||
alert( '12-34-56'.replace("-", ":" ) ) // 12:34-56
|
||||
alert( '12-34-56'.replace("-", ":") ) // 12:34-56
|
||||
```
|
||||
|
||||
При вызове со строкой замены `replace` всегда заменяет только первое совпадение.
|
||||
**При вызове со строкой замены `replace` всегда заменяет только первое совпадение.**
|
||||
|
||||
**Чтобы заменить *все* совпадения, нужно использовать для поиска не строку `"-"`, а регулярное выражение <code class="pattern">/-/g</code>, причём обязательно с флагом `g`:**
|
||||
Чтобы заменить *все* совпадения, нужно использовать для поиска не строку `"-"`, а регулярное выражение <code class="pattern">/-/g</code>, причём обязательно с флагом `g`:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
|
@ -218,19 +220,23 @@ alert( str.replace( /Василий Пупкин/ ,'Великий $&!') ) // В
|
|||
var i = 0;
|
||||
|
||||
// заменить каждое вхождение "ой" на результат вызова функции
|
||||
alert( "ОЙ-Ой-ой".replace( /ой/gi, function() { return ++i; }) ); // 1-2-3
|
||||
alert( "ОЙ-Ой-ой".replace( /ой/gi, function() {
|
||||
return ++i;
|
||||
}) ); // 1-2-3
|
||||
```
|
||||
|
||||
Эта функция также получает аргументы:
|
||||
В примере выше функция просто возвращала числа по очереди, но обычно она основывается на поисковых данных.
|
||||
|
||||
Эта функция получает следующие аргументы:
|
||||
|
||||
<ol>
|
||||
<li>`str` -- найденное совпадение,</li>
|
||||
<li>`p1, p2, ..., pn` -- содержимое скобок</li>
|
||||
<li>`offset` -- позиция, на которой найдено совпадение</li>
|
||||
<li>`s` -- исходная строка</li>
|
||||
<li>`p1, p2, ..., pn` -- содержимое скобок (если есть),</li>
|
||||
<li>`offset` -- позиция, на которой найдено совпадение,</li>
|
||||
<li>`s` -- исходная строка.</li>
|
||||
</ol>
|
||||
|
||||
Если скобок в регулярном выражении нет, то у функции всегда будет ровно 3 аргумента.
|
||||
Если скобок в регулярном выражении нет, то у функции всегда будет ровно 3 аргумента: `replacer(str, offset, s)`.
|
||||
|
||||
Используем это, чтобы вывести полную информацию о совпадениях:
|
||||
|
||||
|
@ -239,35 +245,31 @@ alert( "ОЙ-Ой-ой".replace( /ой/gi, function() { return ++i; }) ); // 1-2
|
|||
// вывести и заменить все совпадения
|
||||
function replacer(str, offset, s) {
|
||||
alert("Найдено: " + str + " на позиции: " + offset + " в строке: " + s);
|
||||
return ":"
|
||||
return str.toLowerCase();
|
||||
}
|
||||
|
||||
var result = "ОЙ-Ой-ой".replace( /ой/gi, replacer);
|
||||
alert('Результат: ' + result);
|
||||
alert('Результат: ' + result); // Результат: ой-ой-ой
|
||||
```
|
||||
|
||||
Со скобочными выражениями:
|
||||
С двумя скобочными выражениями -- аргументов уже 5:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
function replacer(str, name, surname, offset, s) {
|
||||
return surname +", " + name;
|
||||
return surname + ", " + name;
|
||||
}
|
||||
|
||||
alert( str.replace( /(Василий) (Пупкин)/ , replacer) ) // Пупкин, Василий
|
||||
```
|
||||
|
||||
Функция для замены -- это самое мощное средство, какое только может быть. Она владеет всей информацией о совпадении и имеет доступ к замыканию, поэтому может всё.
|
||||
Функция -- это самый мощный инструмент для замены, какой только может быть. Она владеет всей информацией о совпадении и имеет доступ к замыканию, поэтому может всё.
|
||||
|
||||
## Методы объектов RegExp
|
||||
## regexp.test(str)
|
||||
|
||||
Регэкспы являются объектами класса [:RegExp].
|
||||
Теперь переходим к методам класса `RegExp`.
|
||||
|
||||
У них есть два основных метода.
|
||||
|
||||
### regexp.test(str)
|
||||
|
||||
Проверяет, есть ли хоть одно совпадение в строке `str`. Возвращает `true/false`.
|
||||
Метод `test` проверяет, есть ли хоть одно совпадение в строке `str`. Возвращает `true/false`.
|
||||
|
||||
Работает, по сути, так же, как и проверка `str.search(regexp) != -1`, например:
|
||||
|
||||
|
@ -275,6 +277,7 @@ alert( str.replace( /(Василий) (Пупкин)/ , replacer) ) // Пупк
|
|||
//+ run
|
||||
var str = "Люблю регэкспы я, но странною любовью";
|
||||
|
||||
// эти две проверки идентичны
|
||||
alert( *!*/лю/i*/!*.test(str) ) // true
|
||||
alert( str.search(*!*/лю/i*/!*) != -1 ) // true
|
||||
```
|
||||
|
@ -289,9 +292,16 @@ alert( *!*/javascript/i*/!*.test(str) ) // false
|
|||
alert( str.search(*!*/javascript/i*/!*) != -1 ) // false
|
||||
```
|
||||
|
||||
### regexp.exec(str)
|
||||
## regexp.exec(str)
|
||||
|
||||
Этот метод -- самое мощное, что только есть для поиска с использованием регулярных выражений.
|
||||
Для поиска мы уже видели методы:
|
||||
<ul>
|
||||
<li>`search` -- ищет индекс</li>
|
||||
<li>`match` -- если регэксп без флага `g` -- ищет совпадение с подрезультатами в скобках</li>
|
||||
<li>`match` -- если регэксп с флагом `g` -- ищет все совпадения, но без скобочных групп.</li>
|
||||
</ul>
|
||||
|
||||
Метод `regexp.exec` дополняет их. Он позволяет искать и все совпадения и скобочные группы в них.
|
||||
|
||||
Он ведёт себя по-разному, в зависимости от того, есть ли у регэкспа флаг `g`.
|
||||
|
||||
|
@ -300,7 +310,7 @@ alert( str.search(*!*/javascript/i*/!*) != -1 ) // false
|
|||
<li>Если флаг `g` есть, то вызов `regexp.exec` возвращает первое совпадение и *запоминает* его позицию в свойстве `regexp.lastIndex`. Последующий поиск он начнёт уже с этой позиции. Если совпадений не найдено, то сбрасывает `regexp.lastIndex` в ноль.</li>
|
||||
</ul>
|
||||
|
||||
Второй вариант запуска обычно используют в цикле:
|
||||
Это используют для поиска всех совпадений в цикле:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
|
@ -323,7 +333,7 @@ alert('Конечное значение lastIndex: ' + regexp.lastIndex);
|
|||
Найденные результаты последовательно помещаются в `result`, причём находятся там в том же формате, что и `match` -- с учётом скобок, со свойствами `result.index` и `result.input`.
|
||||
|
||||
[smart header="Поиск с нужной позиции"]
|
||||
Технически, можно заставить `regexp.exec` искать сразу с нужной позиции, если поставить `lastIndex` вручную:
|
||||
Можно заставить `regexp.exec` искать сразу с нужной позиции, если поставить `lastIndex` вручную:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
|
@ -334,7 +344,6 @@ regexp.lastIndex = 40;
|
|||
|
||||
alert( regexp.exec(str).index ); // 49, поиск начат с 40й позиции
|
||||
```
|
||||
|
||||
[/smart]
|
||||
|
||||
## Итого, рецепты
|
||||
|
@ -372,5 +381,5 @@ alert( regexp.exec(str).index ); // 49, поиск начат с 40й позиц
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
Далее мы перейдём к более подробному изучению синтаксиса регулярных выражений.
|
||||
Теперь, зная общие методы, мы можем перейти к более подробному изучению синтаксиса регулярных выражений.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Символьные классы
|
||||
# Символьные классы [todo]
|
||||
|
||||
Рассмотрим задачу -- есть телефонный номер `"+7(903)-123-45-67"`, и нам нужно найти в этой строке цифры, а остальные символы нас не интересуют.
|
||||
|
||||
|
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |