Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

103
Vistas
Reemplace la cadena con múltiples valores, sin interferencias

Digamos, tengo una cadena para ser reemplazada:

 let searches = ['gone', 'go', 'run'] let s = 'go went gone-go' const lookup = { 'go': '(go)', 'gone': '[gone]', } for (let key of searches) { s = s.replaceAll(key, lookup[key]) } console.log(s)

Y obtengo (go) went [(go)ne]-(go) . Suponga que s puede ser cualquier cadena con algunas palabras de las claves de lookup , y los valores de lookup no necesariamente tendrán patrones consistentes. searches es la variable de entradas externas.

Si cambio los órdenes en las searches a, por ejemplo, ['go', 'gone', 'run'] , el resultado se convierte en (go) went (go)ne-(go) .

El resultado que espero es (go) went [gone]-(go) , de modo que los más largos se reemplazan primero y no serán reemplazados por coincidencias posteriores.

Se me ocurrió una solución que reemplazaba los valores de búsqueda a uuid primero, iterando de claves más largas a más cortas, luego reemplazaba uuid con los valores correspondientes. Por supuesto, esto es bastante estúpido e ineficiente:

 let searches = ['go', 'gone', 'run'] let s = 'go went gone-go' const lookup = { 'go': '(go)', 'gone': '[gone]', } const uuid = () => Date.now().toString(36) + Math.random().toString(36).substring(2) // pseudo uuid for quick demo. src: https://stackoverflow.com/a/44078785/17954892 let uuidKeys = {} Object.keys(lookup).forEach(k => uuidKeys[k] = uuid()) // uuidKeys = {'go': 'random1', 'gone': 'random2'} let uuids = Object.values(uuidKeys) // uuids = ['random1', 'random2'] let uuidValues = {} Object.keys(lookup).forEach((k, i) => uuidValues[uuids[i]] = lookup[k]) // uuidValues = {'random1': '(go)', 'random2': '[gone]'} searches.sort((a, b) => b.length -a.length) // searches = ['gone', 'run', 'go'] for (let key of searches) { s = s.replaceAll(key, uuidKeys[key]) // s = 'random1 went random2-random1' } for (let key of searches.map(i => uuidKeys[i])) { s = s.replaceAll(key, uuidValues[key]) // s = '(go) went [gone]-(go)' } console.log(s)

Luego pensé en dividir en bucle la cadena por búsquedas, luego reemplazar y registrar el índice que se procesa, y finalmente volver a unir la lista a la cadena. Sin embargo, no puedo encontrar una buena manera de implementarlo sin costosos métodos de matriz (plano, empalme, etc.) en bucles for.

¿Hay una forma elegante/eficiente de lograr el resultado?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Puede hacer esto usando una expresión regular con el indicador g con replace , pasando una función de devolución de llamada como reemplazo; Luego, la función elige el reemplazo apropiado en función de lo que coincida.

Por ejemplo:

 let searches = ["gone", "go", "run"]; let s = "go went gone-go"; const lookup = { "go": "(go)", "gone": "[gone]", }; let rex = new RegExp(searches.map(escapeRegex).join("|"), "g"); s = s.replace(rex, match => lookup[match]); console.log(s);

...donde escapeRegex escapa a cualquier carácter en las cadenas de búsqueda que tengan un significado especial en las expresiones regulares; vea las respuestas de esta pregunta para posibles implementaciones.

Ejemplo en vivo:

 function escapeRegex(string) { return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); } let searches = ["gone", "go", "run"]; let s = "go went gone-go"; const lookup = { "go": "(go)", "gone": "[gone]", }; let rex = new RegExp(searches.map(escapeRegex).join("|"), "g"); s = s.replace(rex, match => lookup[match]); console.log(s); // "(go) went [gone]-(go)"

Nota: El orden de las cadenas en la matriz de searches es importante. Si pones "go" antes de "gone" , coincidirá primero:

 function escapeRegex(string) { return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); } let searches = ["go", "gone", "run"]; // Note −−−−−−−−^ let s = "go went gone-go"; const lookup = { "go": "(go)", "gone": "[gone]", }; let rex = new RegExp(searches.map(escapeRegex).join("|"), "g"); s = s.replace(rex, match => lookup[match]); console.log(s); // "(go) went (go)ne-(go)"

Si siempre desea que el más largo tenga la prioridad más alta y no puede controlar el contenido de la matriz de entrada, puede ordenarlo antes de usarlo:

 function escapeRegex(string) { return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); } let searches = ["go", "gone", "run"]; // Note −−−−−−−−^ let s = "go went gone-go"; const lookup = { "go": "(go)", "gone": "[gone]", }; let rex = new RegExp( searches.sort((a, b) => b.length - a.length) .map(escapeRegex) .join("|"), "g" ); s = s.replace(rex, match => lookup[match]); console.log(s); // "(go) went [gone]-(go)"

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda