Вы можете получить доступ к группам захвата следующим образом:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc
И если есть несколько совпадений, вы можете перебрать их:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
console.log(match[0])
match = myRegexp.exec(myString);
}
Изменить: 2019-09-10
Как видите, способ итерации по нескольким совпадениям был не очень интуитивным. Это привело к предложению String.prototype.matchAll
метода. Ожидается, что этот новый метод будет включен в спецификацию ECMAScript 2020 . Это дает нам чистый API и решает множество проблем. Он был запущен на основных браузерах и движках JS, таких как Chrome 73+ / Node 12+ и Firefox 67+.
Метод возвращает итератор и используется следующим образом:
const string = "something format_abc";
const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
const matches = string.matchAll(regexp);
for (const match of matches) {
console.log(match);
console.log(match.index)
}
Поскольку он возвращает итератор, мы можем сказать, что он ленив, это полезно при обработке особенно большого количества групп захвата или очень больших строк. Но если вам нужно, результат можно легко преобразовать в массив, используя синтаксис расширения или Array.from
метод:
function getFirstGroup(regexp, str) {
const array = [...str.matchAll(regexp)];
return array.map(m => m[1]);
}
// or:
function getFirstGroup(regexp, str) {
return Array.from(str.matchAll(regexp), m => m[1]);
}
Пока же это предложение получает более широкую поддержку, вы можете использовать официальный пакет shim .
Кроме того, внутренняя работа метода проста. Эквивалентная реализация с использованием функции генератора будет выглядеть следующим образом:
function* matchAll(str, regexp) {
const flags = regexp.global ? regexp.flags : regexp.flags + "g";
const re = new RegExp(regexp, flags);
let match;
while (match = re.exec(str)) {
yield match;
}
}
Копия оригинального регулярного выражения создана; это позволяет избежать побочных эффектов из-за мутации lastIndex
свойства при прохождении нескольких совпадений.
Также нам нужно убедиться, что регулярное выражение имеет глобальный флаг, чтобы избежать бесконечного цикла.
Я также рад видеть, что даже этот вопрос StackOverflow упоминался в обсуждениях предложения .
var match = myString.match(myRegexp); // alert(match[1])
:?string = string.substring(match.index + match[0].length)
Вот метод, который вы можете использовать, чтобы получить n- ую группу захвата для каждого совпадения:
источник
Это
\b
не совсем то же самое. (Это работает--format_foo/
, но не работаетformat_a_b
) Но я хотел показать альтернативу вашему выражению, что хорошо. Конечно,match
звонок - важная вещь.источник
format_a_b
", как после 6 лет назад, и я не помню, что я имел в виду ... :-) Полагаю, это означало "не работаетa
только для захвата ", то есть. первая алфавитная часть послеformat_
.Что касается приведенных выше примеров скобок с несколькими совпадениями, я искал здесь ответ, не получив того, что хотел:
Посмотрев на слегка запутанные вызовы функций с помощью while и .push () выше, я понял, что проблема может быть очень элегантно решена с помощью mystring.replace () вместо этого (замена - это НЕ точка, и даже не сделано , ЧИСТАЯ, опция встроенного рекурсивного вызова функции для второго параметра есть!):
После этого я не думаю, что когда-либо снова буду использовать .match () для чего-либо.
источник
И последнее, но не менее важное: я нашел одну строку кода, которая отлично сработала для меня (JS ES6):
Это вернет:
источник
replace
Терминология, использованная в этом ответе:
someString.match(regexPattern)
./format_(.*?)/g
, где(.*?)
будет сопоставленная группа.) Они находятся в согласованных шаблонах .Описание
Чтобы получить доступ к сопоставленным группам , в каждом из сопоставленных шаблонов вам нужна функция или нечто подобное для итерации по совпадению . Есть много способов сделать это, как показывают многие другие ответы. Большинство других ответов используют цикл while для итерации по всем сопоставленным шаблонам , но я думаю, что мы все знаем о потенциальных опасностях такого подхода. Необходимо сопоставлять
new RegExp()
вместо самого шаблона, который упоминается только в комментарии. Это связано с тем, что.exec()
метод ведет себя аналогично функции генератора - он останавливается каждый раз, когда происходит совпадение , но сохраняет его.lastIndex
для продолжения оттуда при следующем.exec()
вызове.Примеры кода
Ниже приведен пример функции,
searchString
которая возвращает одинArray
из всех сопоставленных шаблонов , где каждыйmatch
представляет собойArray
со всеми содержащимися сопоставленными группами . Вместо использования цикла while, я привел примеры, использующие какArray.prototype.map()
функцию, так и более производительный способ - использование обычногоfor
-loop.Краткие версии (меньше кода, больше синтаксического сахара)
Они менее производительны, так как они в основном реализуют
forEach
-loop вместо более быстрогоfor
-loop.Версии Performant (больше кода, меньше синтаксического сахара)
Мне еще предстоит сравнить эти альтернативы с ранее упомянутыми в других ответах, но я сомневаюсь, что этот подход менее эффективен и менее надежен, чем другие.
источник
String#matchAll
(см. черновой вариант 3 / предложение от 7 декабря 2018 г. ) упрощает доступ ко всем группам в объекте сопоставления (помните, что группа 0 - это полное совпадение, в то время как другие группы соответствуют группам захвата в шаблоне):Этот метод дает аналогичный вывод
Regex.Matches
в C #,re.finditer
в Python,preg_match_all
в PHP.См. Демонстрацию JS (протестировано в Google Chrome 73.0.3683.67 (официальная сборка), бета-версия (64-разрядная версия)):
В
console.log([...matches])
шоуВы также можете получить значение соответствия или конкретные значения группы, используя
ПРИМЕЧАНИЕ . См. Сведения о совместимости браузера .
источник
Ваш синтаксис, вероятно, не лучший для сохранения. FF / Gecko определяет RegExp как расширение функции.
(FF2 дошел до
typeof(/pattern/) == 'function'
)Кажется, что это специфично для FF - IE, Opera и Chrome все бросают исключения для него.
Вместо этого используйте любой метод, ранее упомянутый другими:
RegExp#exec
илиString#match
.Они предлагают одинаковые результаты:
источник
Нет необходимости вызывать
exec
метод! Вы можете использовать метод "match" прямо в строке. Просто не забывайте скобки.Позиция 0 содержит строку со всеми результатами. Позиция 1 имеет первое совпадение, представленное круглыми скобками, а позиция 2 имеет второе совпадение, изолированное в ваших круглых скобках. Вложенные скобки сложны, так что будьте осторожны!
источник
Один вкладыш, который практичен, только если у вас есть одна пара круглых скобок:
источник
while (match = myRegex.exec(myStr)) matches.push(match[1])
Используя ваш код:
Изменить: Safari 3, если это имеет значение.
источник
С es2018 вы можете теперь
String.match()
с именованными группами, делает ваше регулярное выражение более явным из того, что он пытался сделать.и вы получите что-то вроде
источник
источник
Ваш код работает для меня (FF3 на Mac), даже если я согласен с PhiLo, что регулярное выражение должно быть:
(Но, конечно, я не уверен, потому что я не знаю контекст регулярного выражения.)
источник
источник
Вам на самом деле не нужен явный цикл для анализа нескольких совпадений - передайте функцию замены в качестве второго аргумента, как описано в
String.prototype.replace(regex, func)
:m0
Аргумент представляет полную найденную подстроку{0}
,{1}
и т.д.m1
представляет собой первую группу соответствия, то есть та часть , заключенная в скобках в регулярном выражении , который0
для первого матча. Иposition
является начальным индексом в строке, где была найдена соответствующая группа - в этом случае не используется.источник
В коде \ 1 представлено соответствие первой группе ([az])
источник
Одноканальное решение:
Таким образом, вы можете использовать этот способ (необходимо использовать / г):
результат:
источник
Получить все вхождения группы
источник
Если вы похожи на меня и хотите, чтобы регулярные выражения возвращали объект как этот:
затем отрежьте функцию снизу
источник
ПРОСТО ИСПОЛЬЗУЙТЕ RegExp. $ 1 ... $ n-ю группу, например:
1. Для соответствия 1-й группе RegExp. $ 1
если вы используете 3 группы в регулярных выражениях подобно (обратите внимание на использование после string.match (регулярное выражение))
RegExp. $ 1 RegExp. $ 2 RegExp. $ 3
источник