Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

102
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda