Alternativa de JavaScript a los cuantificadores posesivos en Regex dynamic

Estoy usando JavaScript para extraer un subconjunto de “hermanos” de una cadena de miembros delimitada por comas que llamo una cadena de “generación”.

Hablando metafóricamente, todos los miembros son de la misma generación, pero no todos son hermanos (de los mismos padres). Aquí hay un ejemplo:

// This is the generation string to search var generation = 'ABAA,ABAB,ABAC,ABAD,ABBA,ACAA,ACAB,ACAD,AEAB,AEAD,AFAA'; // This is the member for whom to extract siblings (member included) var member = 'ACAA'; 

La cadena de generación y sus miembros tienen las siguientes características:

  • Cada miembro tiene la misma cantidad de caracteres que los demás.
  • Todos los miembros de la cadena están ordenados alfa
  • Cada grupo de hermanos siempre estará adyacente entre sí.
  • Los hermanos son aquellos miembros que comparten exactamente la misma combinación de letras, excepto la última letra.

Continuando con el ejemplo …

 // This is how I go about extracting the desired result: ACAA,ACAB,ACAD var mParent = member.substr(0, member.length - 1) ; var mPattern = mParent + '[AZ]'; var mPattern = '(.*)((' + mPattern + ')(,$1)*)(.*)'; // Trouble is here var mRegex = new RegExp(mPattern); var mSiblings = generation.replace(mRegex, '$2'); 

El punto de problema identificado anteriormente concierne a los cuantificadores de expresiones regulares en el patrón construido. Como se muestra arriba, todo está configurado como codicioso, por lo que el valor de mSiblings es:

 ACAD 

Ese es sólo el último miembro. Cambiar mPattern para que sea menos codicioso con la esperanza de extraer a los otros miembros produce lo siguiente

 // Reluctant first expression yields ACAA var mPattern = '(.*?)((' + mPattern + ')(,$1)*)(.*)'; // Reluctant last expression yields ACAD,AEAB,AEAD,AFAA var mPattern = '(.*)((' + mPattern + ')(,$1)*)(.*?)'; // Reluctant first and last yields ACAA,ACAB,ACAD,AEAB,AEAD,AFAA var mPattern = '(.*?)((' + mPattern + ')(,$1)*)(.*?)'; 

Si pudiera hacer que la expresión media sea posesiva, esto sería un problema resuelto. Algo como esto:

 // Make as many "middle" matches as possible by changing (,$1)* to (,$1)*+ var mPattern = '(.*?)((' + mPattern + ')(,$1)*+)(.*?)'; 

Pero como he leído (y tengo los errores de syntax para probarlo), JavaScript no es compatible con cuantificadores posesivos de expresiones regulares. ¿Alguien puede sugerir una solución? Gracias.

El problema más obvio es el $1 . Dentro de una expresión regular, se referiría a la captura del grupo # 1 usando \1 , no $1 . El (,$1)* en su expresión regular nunca va a coincidir con nada. Pero una referencia de grupo no va a hacer ningún bien de todos modos.

Cuando utiliza una referencia de grupo en una expresión regular, no está aplicando esa parte de la expresión regular de nuevo, simplemente está emparejando lo mismo que la primera vez. Es decir, (ACA[AZ])(,\1)* coincidirá con ACAA,ACAA , pero no ACAA,ACAB o ACAA,ACAC . Si desea hacerlo, debe repetir la expresión regular real: (ACA[AZ])(,ACA[AZ])* . Ya que estás generando la expresión regular de forma dinámica, eso no debería ser un problema.

Tenga en cuenta que esa es toda la expresión regular: ACA[AZ](,ACA[AZ])* . No es necesario que coincida con lo que precede o sigue a la parte que le interesa; eso solo hace que el trabajo sea más complicado (y los resultados más confusos). Puede acceder al resultado del partido directamente, en lugar de usar ese truco de “reemplazar”:

 var match = mRegex.exec(generation); if (match != null) { mSiblings = match[0]; } 
Intereting Posts