Estoy buscando hacer reemplazos en entradas desconocidas de terceros en cadenas que a veces tienen comillas entre ellas.
Quiero reemplazar una palabra completa dondequiera que aparezca, a menos que esté entre comillas simples o dobles, y a menos que se escape la comilla.
Ejemplo: Sustitución de FOO por BAR
Aporte:
FOO "FOO" 'FOO' " 1 + FOO + 2 " ABCFOOXYZ " str1\"FOO\"str3'FOO'\'\'" ' str1\'FOOstr3"FOO"\"\"' \"FOO\"Rendimiento esperado:
BAR "FOO" 'FOO' " 1 + FOO + 2 " ABCFOOXYZ " str1\"FOO\"str3'FOO'\'\'" ' str1\'FOOstr3"FOO"\"\"' \"BAR\"Más pruebas:
name: FOO favoriteQuote: "I am my own FOO." children: 'FOO\'s children' cars: ownersList[FOO] statement = FOO + " is the owner of the house."Rendimiento esperado:
name: BAR favoriteQuote: "I am my own FOO." children: 'FOO\'s children' cars: ownersList[BAR] statement = BAR + " is the owner of the house."Vi esta pregunta: haga coincidir y reemplace una palabra que no esté entre comillas (la cadena contiene comillas escapadas) que pensé que era similar y podría ser un buen punto de partida, la respuesta aceptada no funciona en absoluto:
https://regex101.com/r/Lfan64/5
Si alguien pudiera ayudarme a obtener el resultado esperado de mi expresión regular, sería genial, gracias.
Si entiendo sus requisitos correctamente, puede probar esta expresión regular para sus casos:
((['"])(?:\\.|(?!\2).)*(?<!\\)\2)|\bFOO\b/gDemostración RegEx actualizada
Esta expresión regular usa la alternancia para hacer coincidir y descartar lo que necesitamos mantener en LHS de | mientras que en RHS hacemos coincidir lo que queramos reemplazar en el resultado.
Código:
const str = String.raw`name: FOO favoriteQuote: "I am my own FOO." children: 'FOO\'s children' cars: ownersList[FOO] statement = FOO + " is the owner of the house." FOO "FOO" 'FOO' " 1 + FOO + 2 " ABCFOOXYZ " str1\"FOO\"str3'FOO'\'\'" ' str1\'FOOstr3"FOO"\"\"' \"FOO\"`; var repl = str.replace(/((['"])(?:\\.|(?!\2).)*(?<!\\)\2)|\bFOO\b/g, (_, g) => g || "BAR"); console.log(repl);Detalles RegEx:
( : Iniciar grupo de captura #1(['"]) : Coincide con ' o " en el grupo de captura #2(?:\\.|(?!\2).)* : Coincide con un carácter escapado o cualquier carácter excepto la cita que coincidimos en el grupo de captura #2(?<!\\)\2 : Haga coincidir cualquier cita que hayamos encontrado en el grupo de captura #2 siempre que no esté precedida por \) : Fin del grupo de captura #1| : O\bFOO\b : coincide con la palabra completa FOOPuedes usar
const text = String.raw`name: FOO favoriteQuote: "I am my own FOO." children: 'FOO\'s children' cars: ownersList[FOO] statement = FOO + " is the owner of the house." FOO "FOO" 'FOO' " 1 + FOO + 2 " ABCFOOXYZ " str1\"FOO\"str3'FOO'\'\'" ' str1\'FOOstr3"FOO"\"\"' \"FOO\"` console.log( text.replace( /((?:[^\\]|^)(?:\\{2})*(?:"[^"\\]*(?:\\[^][^"\\]*)*"|'[^'\\]*(?:\\[^][^'\\]*)*'))|FOO/g, (match, group) => group || "BAR" ))Detalles :
((?:[^\\]|^)(?:\\{2})*(?:"[^"\\]*(?:\\[^][^"\\]*)*"|'[^'\\]*(?:\\[^][^'\\]*)*')) - Grupo 1:(?:[^\\]|^) - un carácter que no sea \ o el comienzo de la cadena(?:\\{2})* - cero o más secuencias de doble barra invertida(?:"[^"\\]*(?:\\[^][^"\\]*)*"|'[^'\\]*(?:\\[^][^'\\]*)*') - ya sea de un patrón literal de cadena entre comillas simples o dobles con soporte de secuencia de escape| - oFOO : una cadena FOO en cualquier otro contexto. El (match, group) => group || "BAR" El reemplazo (match, group) => group || "BAR" significa que si el Grupo 1 coincide, el reemplazo es el valor del Grupo 1, de lo contrario, el reemplazo es BAR .