en.javascript.info/10-regular-expressions-javascript/09-regexp-backreferences/article.md
Ilya Kantor e2443e8de6 ok
2017-03-19 16:59:53 +03:00

63 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Обратные ссылки: \n и $n
Скобочные группы можно не только получать в результате.
Движок регулярных выражений запоминает их содержимое, и затем его можно использовать как в самом паттерне, так и в строке замены.
[cut]
## Группа в строке замены
Ссылки в строке замены имеют вид `$n`, где `n` -- это номер скобочной группы.
Вместо `$n` подставляется содержимое соответствующей скобки:
```js run
var name = "Александр Пушкин";
name = name.replace(/([а-яё]+) ([а-яё]+)/i, *!*"$2, $1"*/!*);
alert( name ); // Пушкин, Александр
```
В примере выше вместо `pattern:$2` подставляется второе найденное слово, а вместо `pattern:$1` -- первое.
## Группа в шаблоне
Выше был пример использования содержимого групп в строке замены. Это удобно, когда нужно реорганизовать содержимое или создать новое с использованием старого.
Но к скобочной группе можно также обратиться в самом поисковом шаблоне, ссылкой вида `\номер`.
Чтобы было яснее, рассмотрим это на реальной задаче -- необходимо найти в тексте строку в кавычках. Причём кавычки могут быть одинарными `subject:'...'` или двойными `subject:"..."` -- и то и другое должно искаться корректно.
Как такие строки искать?
Можно в регэкспе предусмотреть произвольные кавычки: `pattern:['"](.*?)['"]`. Такой регэксп найдёт строки вида `match:"..."`, `match:'...'`, но он даст неверный ответ в случае, если одна кавычка ненароком оказалась внутри другой, как например в строке `subject:"She's the one!"`:
```js run
var str = "He said: \"She's the one!\".";
var reg = /['"](.*?)['"]/g;
// Результат не соответствует замыслу
alert( str.match(reg) ); // "She'
```
Как видно, регэксп нашёл открывающую кавычку `match:"`, затем текст, вплоть до новой кавычки `match:'`, которая закрывает соответствие.
Для того, чтобы попросить регэксп искать закрывающую кавычку -- такую же, как открывающую, мы обернём её в скобочную группу и используем обратную ссылку на неё:
```js run
var str = "He said: \"She's the one!\".";
var reg = /(['"])(.*?)\1/g;
alert( str.match(reg) ); // "She's the one!"
```
Теперь работает верно! Движок регулярных выражений, найдя первое скобочное выражение -- кавычку `pattern:(['"])`, запоминает его и далее `pattern:\1` означает "найти то же самое, что в первой скобочной группе".
Обратим внимание на два нюанса:
- Чтобы использовать скобочную группу в строке замены -- нужно использовать ссылку вида `$1`, а в шаблоне -- обратный слэш: `\1`.
- Чтобы в принципе иметь возможность обратиться к скобочной группе -- не важно откуда, она не должна быть исключена из запоминаемых при помощи `?:`. Скобочные группы вида `(?:...)` не участвуют в нумерации.