Estoy tratando de extraer varias cadenas usando diferentes patrones de una cadena larga. Aquí hay un ejemplo de la cadena de entrada:
[Actualización 2] Número de estudiantes: 5 [Nuevo] Descanso a la 1:45 p. m.\nLos estudiantes involucrados son: John, Joseph, Maria\nAlmuerzo a las 2:00 p. m.\nActividades restantes: salto de longitud, barajar
Hay tres prefijos que se utilizan para extraer los datos después: 'Los estudiantes involucrados son:', 'Actividades restantes:', 'Número de estudiantes:'. Logré extraer lo anterior en un grupo con nombre usando el siguiente Regex:
let pattern = /(?<=Number of students: )(?<number>[^\n]+).*?(?<=Students involved are: )(?<students>[^\n]+).*?(?<=Activities remaining: )(?<activities>[^\n]+)/gms let match = pattern.exec(s) const num = match.number; const activities = match.activities;Lo anterior funciona. Sin embargo, me encuentro con un problema cuando falta una de las cadenas. Los tres prefijos que estoy buscando son opcionales. ¿Cómo puedo modificar la expresión regular para manejar patrones opcionales? ¿O hay una mejor manera de lograr esto? ¡Gracias!
No estoy seguro de que necesite mirar detrás de las afirmaciones para ese caso de uso ...
Para responder a su pregunta, puede envolver sus patrones individuales dentro de grupos que no capturan seguidos de un signo de interrogación:
const r = /(?:Desc.1:\s*(?<tag1>.*?))?(?:Descr.2:\s*(?<tag2>.*?))?(?:Desc.3:\s*(?<tag3>.*?))?/Si los valores pueden venir en cualquier orden, puede usar una coincidencia global y una disyunción:
const r = /x(?<tag1>.*)|y(?<tag2>.*)|z(?<tag3>.*)/g for (const {groups: {tag1, tag2, tag3}} of source.matchAll(r)) { ... }Puedes verlo en acción aquí
Además, para tu información, las banderas que estás usando no tienen mucho sentido para mí:
g es útil para hacer coincidir varias veces (por ejemplo, con "".matchAll(/regexp/g) , pero de lo contrario es inútil)m hace que las aserciones ^ y $ coincidan con el inicio y el final de las líneas además de su función habitual, pero no las está usandoAquí está mi intento:
"^\[[^\]]+\](Number of students: )*(?<number>[^\n]+)\\n(Students involved are: )*(?<students>[^\n]+)\\n(Activities remaining: )*(?<activities>[^\n]+)"Las diferencias entre el mío y el tuyo son las siguientes:
^\[[^\]]+\] al principio para que coincida con [<any characters>]* sobre las partes opcionales de su cadena\\n entre las tres partes emparejadasHe probado esta expresión regular con estos dos ejemplos:
[Update 2]Number of students: 5[New]Break at 1:45 pm\nStudents involved are: John, Joseph, Maria\nLunch at 2:00pm\nActivities remaining: long jump, shuffle[Update 2]5[New]Break at 1:45 pm\nJohn, Joseph, Maria\nLunch at 2:00pm\nlong jump, shuffle¿Funciona para ti?
PD. para cualquier intento de aumentar la eficiencia, se necesitan más muestras de coincidencia de patrones