Até onde eu sei, não existe o nome de grupos de captura em JavaScript. Qual é a maneira alternativa de obter funcionalidade semelhante?
javascript
regex
mmierins
fonte
fonte
Respostas:
O ECMAScript 2018 introduz grupos de captura nomeados em expressões regulares do JavaScript.
Exemplo:
Se você precisar oferecer suporte a navegadores antigos, poderá fazer tudo com grupos de captura normais (numerados) que você pode fazer com grupos de captura nomeados, basta acompanhar os números - o que pode ser complicado se a ordem do grupo de captura em seu mudanças de regex.
Existem apenas duas vantagens "estruturais" dos grupos de captura nomeados em que posso pensar:
Em alguns tipos de regex (.NET e JGSoft, até onde eu sei), você pode usar o mesmo nome para diferentes grupos em seu regex ( veja aqui um exemplo em que isso importa ). Mas a maioria dos tipos de expressões regulares não suporta essa funcionalidade.
Se você precisar se referir a grupos de captura numerados em uma situação em que eles estão cercados por dígitos, você pode obter um problema. Digamos que você deseja adicionar um zero a um dígito e, portanto, deseja substituir
(\d)
por$10
. Em JavaScript, isso funcionará (contanto que você tenha menos de 10 grupos de capturas em sua regex), mas Perl pensará que você está procurando por um número de referência anterior em10
vez de um número1
, seguido por a0
. No Perl, você pode usar${1}0
neste caso.Fora isso, os grupos de captura nomeados são apenas "açúcar sintático". Ajuda a usar grupos de captura somente quando você realmente precisa deles e a usar grupos que não capturam
(?:...)
em todas as outras circunstâncias.O maior problema (na minha opinião) do JavaScript é que ele não suporta expressões verbais que facilitariam muito a criação de expressões regulares complexas e legíveis.
A biblioteca XRegExp de Steve Levithan resolve esses problemas.
fonte
Você pode usar o XRegExp , uma implementação aumentada, extensível e cruzada de expressões regulares, incluindo suporte para sintaxe, sinalizadores e métodos adicionais:
s
:, para fazer o ponto corresponder a todos os caracteres (também conhecido como modo dotall ou linha única) ex
, para espaçamento livre e comentários (conhecido como modo estendido).fonte
Outra solução possível: crie um objeto contendo os nomes e índices do grupo.
Em seguida, use as teclas de objeto para fazer referência aos grupos:
Isso melhora a legibilidade / qualidade do código usando os resultados da regex, mas não a legibilidade da própria regex.
fonte
No ES6, você pode usar a destruição de matriz para capturar seus grupos:
Aviso prévio:
let
pula o primeiro valor da matriz resultante, que é toda a cadeia correspondente|| []
after.exec()
evitará um erro de desestruturação quando não houver correspondências (porque.exec()
retornaránull
)fonte
String.prototype.match
retorna uma matriz com: toda a cadeia correspondente na posição 0, depois quaisquer grupos depois disso. A primeira vírgula diz "pular o elemento na posição 0"RegExp.prototype.exec
maisString.prototype.match
em lugares onde a string pode sernull
ouundefined
.Atualização: finalmente transformou-se em JavaScript (ECMAScript 2018)!
Grupos de captura nomeados podem entrar no JavaScript muito em breve.
A proposta já está no estágio 3.
Um grupo de captura pode receber um nome entre colchetes angulares usando a
(?<name>...)
sintaxe, para qualquer nome de identificador. A expressão regular de uma data pode ser escrita como/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u
. Cada nome deve ser exclusivo e seguir a gramática para ECMAScript IdentifierName .Grupos nomeados podem ser acessados a partir de propriedades de uma propriedade de grupos do resultado da expressão regular. Também são criadas referências numeradas para os grupos, assim como para grupos sem nome. Por exemplo:
fonte
let {year, month, day} = ((result) => ((result) ? result.groups : {}))(re.exec('2015-01-02'));
A nomeação de grupos capturados fornece uma coisa: menos confusão com expressões regulares complexas.
Realmente depende do seu caso de uso, mas talvez a impressão bonita do seu regex possa ajudar.
Ou você pode tentar definir constantes para se referir aos seus grupos capturados.
Os comentários também podem ajudar a mostrar aos outros que leem seu código, o que você fez.
Quanto ao resto, devo concordar com a resposta de Tims.
fonte
Existe uma biblioteca node.js chamada named-regexp que você pode usar em seus projetos node.js. (ativada no navegador empacotando a biblioteca com o browserify ou outros scripts de empacotamento). No entanto, a biblioteca não pode ser usada com expressões regulares que contêm grupos de captura sem nome.
Se você contar os chavetas de captura de abertura em sua expressão regular, poderá criar um mapeamento entre os grupos de captura nomeados e os grupos de captura numerados em sua regex e poderá misturar e combinar livremente. Você apenas precisa remover os nomes dos grupos antes de usar a regex. Eu escrevi três funções que demonstram isso. Veja esta lista: https://gist.github.com/gbirke/2cc2370135b665eee3ef
fonte
Como Tim Pietzcker disse, o ECMAScript 2018 introduz grupos de captura nomeados nas expressões regulares do JavaScript. Mas o que não encontrei nas respostas acima foi como usar o grupo capturado nomeado no próprio regex.
você pode usar grupo capturado nomeado com a seguinte sintaxe:
\k<name>
. por exemploe, como Forivin disse, você pode usar o grupo capturado no resultado do objeto da seguinte maneira:
fonte
Embora você não possa fazer isso com JavaScript vanilla, talvez você possa usar alguma
Array.prototype
função comoArray.prototype.reduce
transformar correspondências indexadas em nomeadas usando alguma mágica .Obviamente, a seguinte solução precisará que as correspondências ocorram em ordem:
fonte
var assocArray = Regex("hello alex, I am dennis", "hello ({hisName}.+), I am ({yourName}.+)");
RegExp
objeto adicionando uma função ao seu protótipo.Não possui o ECMAScript 2018?
Meu objetivo era fazê-lo funcionar o mais semelhante possível ao que estamos acostumados com grupos nomeados. Enquanto no ECMAScript 2018 você pode colocar
?<groupname>
dentro do grupo para indicar um grupo nomeado, na minha solução para javascript antigo, você pode colocar(?!=<groupname>)
dentro do grupo para fazer a mesma coisa. Portanto, é um conjunto extra de parênteses e um extra!=
. Bem perto!Eu envolvi tudo isso em uma função de protótipo de string
Recursos
Instruções
(?!={groupname})
dentro de cada grupo que você deseja nomear()
colocando?:
no início desse grupo. Estes não serão nomeados.arrays.js
uso
resultado de o
fonte