Necesito una expresión regular que coincida (y enumere) todos los 'modificadores' de una cadena. Los modificadores son letras individuales detrás del último : en la cadena. Los modificadores pueden tener variables que se escribirían entre corchetes, por ejemplo, a{variable} . Las variables pueden contener el carácter : -- lo que lo hace un poco complicado, porque debemos buscar el último : que NO está entre { y } . Este es actualmente mi mayor problema, vea el Ejemplo 6 a continuación.
(Si es importante, el idioma de destino para esto será javascript).
Ya tengo esto funcionando para la mayoría de los casos, pero tengo algunos casos extremos en los que no puedo hacer que funcione.
Mi expresión regular hasta ahora es:
/(?!.*:)([az](\{.*?\})*)/gEjemplo 1: modificador único
something:a debe coincidir con a - funciona bien
Ejemplo 2: Múltiples modificadores
something:abc debe coincidir con a , b y c - funcionando bien
Ejemplo 3: modificador único con variable
something:a{something} debe coincidir con a{something} - funciona bien
Ejemplo 4: Modificador único con múltiples variables
something:a{something}{something} debe coincidir con a{something}{something} - funciona bien
Ejemplo 5: Múltiples modificadores con variables
something:ab{something}cd{something}{something}efg debe coincidir con a , b{something} , c , d{something}{something} , e , f , g - funciona bien
Ejemplo 6: Variable que contiene :
something:a{something:2} - debe coincidir con a{something:2} - NO funciona. Probablemente necesite modificar la anticipación negativa de alguna manera para ignorar los dos puntos entre llaves, pero no pude averiguar cómo hacerlo.
Ejemplo 7: Cadena que no contiene un :
something : no debe coincidir con nada, pero coincide con cada letra individualmente. Esto puede o no ser fácil de arreglar, pero mi cerebro actualmente no puede resolverlo.
Aquí hay un enlace para probar/jugar con esta expresión regular y los ejemplos: https://regexr.com/6h4h0
Si alguien puede ayudarme a descubrir cómo hacer que la expresión regular funcione para los ejemplos 6 y 7, ¡estaría muy agradecido!
Puedes usar
const regex = /.*:((?:[a-zA-Z](?:{[^{}]*})*)+)$/; const extract_rx = /[a-zA-Z](?:{[^{}]*})*/g; const texts = ['something:a','something:abc','something:a{something}','something:a{something}{something}','something:ab{something}cd{something}{something}efg','something:a{something:2}','something:a{something:2}b{something:3}','something']; for (const text of texts) { const m = text.match(regex); if (m) { const matches = m[1].match(extract_rx); console.log(text, '=>', matches); } else { console.log(text, '=> NO MATCH'); } }Vea la demostración principal de expresiones regulares . Detalles :
.*: - coincide con cualquier cero o más caracteres que no sean caracteres de salto de línea tantos como sea posible y luego un : seguido de...((?:[a-zA-Z](?:{[^{}]*})*)+) - Grupo 1: una o más secuencias de[a-zA-Z] - una letra ASCII(?:{[^{}]*})* - cero o más secuencias de un { , cero o más caracteres que no sean { y } y luego un } carácter$ - final de la cadena. Una vez que hay una coincidencia, el Grupo 1 se analiza nuevamente para extraer todas las secuencias de una letra y luego cualquier subcadena cero o más {...} inmediatamente después.
Lo que podría hacer en su lugar es asegurarse de que haya dos puntos en algún lugar antes de la cadena coincidente con una mirada positiva detrás.
Esencialmente cambiando (?!.*:) por (?<=:.*) .
const regex = /(?<=:.*)([az](\{.*?\})*)/g; const strings = [ "something:a", "something:abc", "something:a{something}", "something:a{something}{something}", "something:ab{something}cd{something}{something}efg", "something:a{something:2}", "something", ]; for (const string of strings) { console.log(string.match(regex)); }No estoy seguro si esto es lo que quieres:
:([az\{.*?\}0-9])*Lo intentaría más tiempo, pero tengo que ir a tomar un vuelo.