Estou tentando analisar seqüências de caracteres codificadas em URL que são compostas de pares chave = valor separados por um &
ou outro&
.
O seguinte corresponderá apenas à primeira ocorrência, dividindo as chaves e os valores em elementos de resultado separados:
var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/)
Os resultados para a sequência '1111342 = Adam% 20Franco & 348572 = Bob% 20Jones' seriam:
['1111342', 'Adam%20Franco']
O uso do sinalizador global 'g' corresponderá a todas as ocorrências, mas retornará apenas as sub-sequências totalmente correspondentes, não as chaves e valores separados:
var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/g)
Os resultados para a sequência '1111342 = Adam% 20Franco & 348572 = Bob% 20Jones' seriam:
['1111342=Adam%20Franco', '&348572=Bob%20Jones']
Embora eu possa dividir a string &
e separar cada par de chave / valor individualmente, há alguma maneira de usar o suporte à expressão regular do JavaScript para corresponder a várias ocorrências do padrão /(?:&|&)?([^=]+)=([^&]+)/
semelhante ao PHPpreg_match_all()
função ?
Estou buscando uma maneira de obter resultados com as sub-correspondências separadas como:
[['1111342', '348572'], ['Adam%20Franco', 'Bob%20Jones']]
ou
[['1111342', 'Adam%20Franco'], ['348572', 'Bob%20Jones']]
fonte
replace
aqui.var data = {}; mystring.replace(/(?:&|&)?([^=]+)=([^&]+)/g, function(a,b,c,d) { data[c] = d; });
feito. "matchAll" no JavaScript é "replace" por uma função de manipulador de substituição em vez de uma string.Respostas:
Içado dos comentários
O suporte ao navegador está listado aqui https://caniuse.com/#feat=urlsearchparams
Eu sugeriria uma regex alternativa, usando subgrupos para capturar o nome e o valor dos parâmetros individualmente e
re.exec()
:result
é um objeto:A regex é dividida da seguinte maneira:
fonte
x = y
seria atribuiry
ax
e também produzemy
). Quando aplicamos esse conhecimento aif (match = re.exec(url))
: Este A) faz a atribuição e B) retorna o resultado dere.exec(url)
para owhile
. Agorare.exec
retornanull
se não houver correspondência, que é um valor falso. Portanto, o loop continuará enquanto houver uma correspondência.Você precisa usar o botão 'g' para uma pesquisa global
fonte
2020 editar
Use URLSearchParams , pois esse trabalho não requer mais nenhum tipo de código personalizado. Os navegadores podem fazer isso por você com um único construtor:
rendimentos
Portanto, não há mais razão para usar o regex para isso.
Resposta original
Se você não deseja confiar na "correspondência cega" que vem com a
exec
correspondência de estilos de execução , o JavaScript vem com a funcionalidade correspondente a todas incorporada, mas faz parte dareplace
chamada de função ao usar um "o que fazer com a captura" função de manipulação de grupos " :feito.
Em vez de usar a função de tratamento do grupo de captura para realmente retornar seqüências de substituição (para o tratamento de substituição, o primeiro argumento é a correspondência completa de padrões e os argumentos subsequentes são grupos de captura individuais), simplesmente pegamos as capturas dos grupos 2 e 3 e colocamos em cache esse par.
Portanto, em vez de escrever funções de análise complicadas, lembre-se de que a função "matchAll" no JavaScript é simplesmente "substituir" por uma função manipuladora de substituição, e pode-se obter muita eficiência na correspondência de padrões.
fonte
something "this one" and "that one"
. Eu quero colocar todas as seqüências de caracteres duplas entre aspas em uma lista, ou seja, [este, aquele]. Até agora,mystring.match(/"(.*?)"/)
funciona bem em detectar o primeiro, mas não sei como adaptar sua solução para um único grupo de captura.Para capturar grupos, estou acostumado a usar
preg_match_all
no PHP e tentei replicar sua funcionalidade aqui:fonte
/g
caso contrário a execuçãoexec()
não mudará o índice atual e fará um loop para sempre.Defina o
g
modificador para uma correspondência global:fonte
Fonte:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
Localizando correspondências sucessivas
Se sua expressão regular usa o sinalizador "g", você pode usar o método exec () várias vezes para encontrar correspondências sucessivas na mesma string. Quando você faz isso, a pesquisa inicia na substring de str especificada pela propriedade lastIndex da expressão regular (test () também avançará na propriedade lastIndex). Por exemplo, suponha que você tenha este script:
Este script exibe o seguinte texto:
Nota: Não coloque a expressão regular literal (ou construtor RegExp) na condição while ou isso criará um loop infinito se houver uma correspondência devido à propriedade lastIndex sendo redefinida a cada iteração. Verifique também se o sinalizador global está definido ou se ocorrerá um loop aqui também.
fonte
String.prototype.match
com ag
bandeira:'abbcdefabh'.match(/ab*/g)
retornos['abb', 'ab']
Se alguém (como eu) precisa do método Tomalak com suporte a array (ou seja, seleção múltipla), aqui está:
entrada
?my=1&my=2&my=things
resultado
1,2,things
(retornado anteriormente apenas: coisas)fonte
Apenas para ficar com a pergunta proposta, conforme indicado pelo título, você pode realmente interagir com cada correspondência em uma string usando
String.prototype.replace()
. Por exemplo, o seguinte faz exatamente isso para obter uma matriz de todas as palavras com base em uma expressão regular:Se eu quisesse obter grupos de captura ou até o índice de cada partida, eu também poderia fazer isso. A seguir, mostramos como cada correspondência é retornada com a correspondência inteira, o 1º grupo de capturas e o índice:
Depois de executar o acima,
words
será o seguinte:Para combinar várias ocorrências semelhantes ao que está disponível no PHP,
preg_match_all
você pode usar esse tipo de pensamento para criar o seu próprio ou usar algo parecidoYourJS.matchAll()
. YourJS define mais ou menos essa função da seguinte maneira:fonte
YourJS.parseQS()
( yourjs.com/snippets/56 ), embora muitas outras bibliotecas também ofereçam essa funcionalidade.Se você pode se dar bem usando
map
esta é uma solução de quatro linhas:Não é bonito, não é eficiente, mas pelo menos é compacto. ;)
fonte
Use
window.URL
:fonte
Olá, a partir de 2020. Deixe-me chamar sua atenção a String.prototype.matchAll () :
Saídas:
fonte
Para capturar vários parâmetros usando o mesmo nome, modifiquei o loop while no método do Tomalak desta maneira:
entrada:
?firstname=george&lastname=bush&firstname=bill&lastname=clinton
retorna:
{firstname : ["george", "bill"], lastname : ["bush", "clinton"]}
fonte
?cinema=1234&film=12&film=34
seria de esperar{cinema: 1234, film: [12, 34]}
. Editou sua resposta para refletir isso.Bem ... Eu tive um problema semelhante ... Quero uma pesquisa incremental / passo com o RegExp (por exemplo: iniciar pesquisa ... faça algum processamento ... continue a pesquisa até a última correspondência)
Depois de muita pesquisa na Internet ... como sempre (isso está se tornando um hábito agora), acabo no StackOverflow e encontrei a resposta ...
O que não é referido e o que é importante mencionar é "
lastIndex
" Agora entendo por que o objeto RegExp implementa alastIndex
propriedade " "fonte
Dividir parece a melhor opção para mim:
fonte
Para evitar o inferno regular, você pode encontrar sua primeira correspondência, corte um pedaço e tente encontrar o próximo na substring. Em C #, isso se parece com isso, desculpe, eu não o transportei para JavaScript para você.
fonte