Você pode acessar grupos de captura como este:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc
E se houver várias correspondências, você poderá iterar sobre elas:
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);
}
Edição: 2019-09-10
Como você pode ver, a maneira de iterar em várias correspondências não foi muito intuitiva. Isso levou à proposta do String.prototype.matchAll
método. Espera-se que este novo método seja fornecido na especificação ECMAScript 2020 . Ele nos fornece uma API limpa e resolve vários problemas. Ele foi iniciado nos principais navegadores e mecanismos JS como Chrome 73+ / Node 12+ e Firefox 67+.
O método retorna um iterador e é usado da seguinte maneira:
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)
}
Como ele retorna um iterador, podemos dizer que é preguiçoso, isso é útil ao lidar com um número particularmente grande de grupos de captura ou cadeias muito grandes. Mas se você precisar, o resultado poderá ser facilmente transformado em uma matriz usando a sintaxe de propagação ou o Array.from
método:
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]);
}
Enquanto isso, enquanto esta proposta obtém suporte mais amplo, você pode usar o pacote oficial de calço .
Além disso, o funcionamento interno do método é simples. Uma implementação equivalente usando uma função de gerador seria a seguinte:
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;
}
}
Uma cópia do regexp original é criada; isso é para evitar efeitos colaterais devido à mutação da lastIndex
propriedade ao passar pelas correspondências múltiplas.
Além disso, precisamos garantir que o regexp tenha o sinalizador global para evitar um loop infinito.
Também fico feliz em ver que mesmo essa pergunta sobre o StackOverflow foi referenciada nas discussões da proposta .
var match = myString.match(myRegexp); // alert(match[1])
:?string = string.substring(match.index + match[0].length)
Aqui está um método que pode utilizar para obter o n º grupo de captura para cada jogo:
fonte
O
\b
não é exatamente a mesma coisa. (Funciona--format_foo/
, mas não funcionaformat_a_b
) Mas eu queria mostrar uma alternativa à sua expressão, o que é bom. Obviamente, amatch
ligação é importante.fonte
format_a_b
", como pensado há 6 anos, e não me lembro do que eu quis dizer lá ... :-) Suponho que isso significava "não funcionaa
apenas para capturar ", ie a primeira parte alfabética depoisformat_
.Com relação aos exemplos de parênteses com várias correspondências acima, eu estava procurando uma resposta aqui depois de não obter o que queria:
Depois de examinar as chamadas de função levemente complicadas com while e .push () acima, ocorreu-me que o problema pode ser resolvido de maneira muito elegante com mystring.replace () (a substituição NÃO é o objetivo e nem está concluída) , a opção de chamada de função recursiva CLEAN, integrada para o segundo parâmetro é!):
Depois disso, acho que nunca mais vou usar .match () para quase nada.
fonte
Por último, mas não menos importante, encontrei uma linha de código que funcionou bem para mim (JS ES6):
Isso retornará:
fonte
replace
abordagem completa de Alexz, porque essa é menos moderna e mais elegante para vários resultados. Bom trabalho nisso, Sebastien H.Terminologia usada nesta resposta:
someString.match(regexPattern)
./format_(.*?)/g
onde(.*?)
seria um grupo correspondente.) Estes residem dentro dos padrões correspondentes .Descrição
Para obter acesso aos grupos correspondentes , em cada um dos padrões correspondentes , você precisa de uma função ou algo semelhante para iterar durante a correspondência . Existem várias maneiras de fazer isso, como mostram muitas das outras respostas. A maioria das outras respostas usa um loop while para iterar todos os padrões correspondentes , mas acho que todos conhecemos os perigos em potencial com essa abordagem. É necessário fazer a comparação entre a e
new RegExp()
não apenas o próprio padrão, mencionado apenas em um comentário. Isso ocorre porque o.exec()
método se comporta de maneira semelhante a uma função de gerador - ele para sempre que há uma correspondência , mas mantém sua.lastIndex
a continuar a partir daí na próxima.exec()
chamada.Exemplos de código
Abaixo está um exemplo de uma função
searchString
que retorna umArray
de todos os padrões correspondentes , onde cadamatch
um é umArray
com todos os grupos correspondentes correspondentes . Em vez de usar um loop while, forneci exemplos usando ambos osArray.prototype.map()
função e uma maneira maisfor
eficiente - usando um loop simples .Versões concisas (menos código, mais açúcar sintático)
Eles têm menos desempenho, porque basicamente implementam um
forEach
loop em vez do mais rápidofor
.Versões de desempenho (mais código, menos açúcar sintático)
Ainda tenho que comparar essas alternativas com as mencionadas anteriormente nas outras respostas, mas duvido que essa abordagem tenha menos desempenho e menos falhas do que as outras.
fonte
String#matchAll
(consulte a proposta do Estágio 3/7 de dezembro de 2018 ), simplifica o acesso a todos os grupos no objeto de correspondência (lembre-se de que o grupo 0 é a correspondência inteira, enquanto outros grupos correspondem aos grupos de captura no padrão):Este método produz uma saída semelhante à
Regex.Matches
do C #,re.finditer
no Python,preg_match_all
no PHP.Veja uma demonstração JS (testada no Google Chrome 73.0.3683.67 (versão oficial), beta (64 bits)):
Os
console.log([...matches])
showsVocê também pode obter um valor de correspondência ou valores de grupo específicos usando
NOTA : Veja os detalhes de compatibilidade do navegador .
fonte
Sua sintaxe provavelmente não é a melhor para manter. FF / Gecko define RegExp como uma extensão da Function.
(FF2 foi tão longe
typeof(/pattern/) == 'function'
)Parece que isso é específico para o FF - IE, Opera e Chrome - todos lançam exceções.
Em vez disso, use um dos métodos mencionados anteriormente por outras pessoas:
RegExp#exec
ouString#match
.Eles oferecem os mesmos resultados:
fonte
Não há necessidade de chamar o
exec
método! Você pode usar o método "match" diretamente na string. Só não esqueça os parênteses.A posição 0 tem uma sequência com todos os resultados. A posição 1 tem a primeira correspondência representada por parênteses e a posição 2 tem a segunda correspondência isolada entre parênteses. Parênteses aninhados são complicados, então cuidado!
fonte
Um liner único que é prático apenas se você tiver um único par de parênteses:
fonte
while (match = myRegex.exec(myStr)) matches.push(match[1])
Usando seu código:
Edit: Safari 3, se isso importa.
fonte
Com es2018, agora você pode
String.match()
com grupos nomeados, torna seu regex mais explícito do que estava tentando fazer.e você terá algo como
fonte
fonte
Seu código funciona para mim (FF3 no Mac), mesmo que eu concorde com o PhiLo de que o regex provavelmente deve ser:
(Mas, é claro, não tenho certeza porque não conheço o contexto da regex.)
fonte
fonte
Você realmente não precisa de um loop explícito para analisar várias correspondências - passe uma função de substituição como o segundo argumento, conforme descrito em
String.prototype.replace(regex, func)
::O
m0
argumento representa o substring combinada completa{0}
,{1}
etc.m1
representa o primeiro grupo correspondente, ou seja, a parte entre colchetes no regex que é0
para o primeiro jogo. Eposition
é o índice inicial dentro da string em que o grupo correspondente foi encontrado - não utilizado neste caso.fonte
No código \ 1 representado correspondente ao primeiro grupo ([az])
fonte
Solução de uma linha:
Então você pode usar desta maneira (deve usar / g):
resultado:
fonte
Obter toda a ocorrência do grupo
fonte
Eu você é como eu e gostaria que o regex retornasse um Objeto como este:
depois corte a função de baixo
fonte
APENAS USAR RegExp. $ 1 ... $ n º grupo, por exemplo:
1.Para corresponder à 1ª Reg. Do grupo
se você usar 3 grupos no regex likey (observe o uso após string.match (regex))
RegExp. $ 1 RegExp. $ 2 RegExp. $ 3
fonte