¿Cómo reemplazar todas las ocurrencias de una cadena?

4384

Tengo esta cadena:

"Test abc test test abc test test test abc test test abc"

Haciendo:

str = str.replace('abc', '');

parece eliminar solo la primera aparición de abcen la cadena de arriba.

¿Cómo puedo reemplazar todas las ocurrencias?

Haga clic en Upvote
fuente
55
Al reemplazar todas las ocurrencias de abain ababacon ca, ¿qué resultado espera? caba? abca? cca?
reinierpost
String.prototype.replaceAll()enviado en Safari 13.1 y ahora está en Firefox Nightly y Chrome Dev y Canary y se enviará en Firefox 77 y Chrome 85. Todavía no está documentado en MDN, pero github.com/tc39/proposal-string-replaceall#high-level-api tiene un explicador: "Si searchValue es una cadena, String.prototype.replaceAllreemplaza todas las apariciones de searchValue (como si se .split(searchValue).join(replaceValue)hubiera utilizado una expresión regular global y con escape correcto ). Si searchValue es una expresión regular no global, String.prototype.replaceAllgenera una excepción ”
sideshowbarker

Respuestas:

1612

Nota: No use esto en el código crítico de rendimiento.

Como alternativa a las expresiones regulares para una cadena literal simple, podría usar

str = "Test abc test test abc test...".split("abc").join("");

El patrón general es

str.split(search).join(replacement)

Esto solía ser más rápido en algunos casos que usar replaceAlly una expresión regular, pero ese ya no parece ser el caso en los navegadores modernos.

Punto de referencia: https://jsperf.com/replace-all-vs-split-join

Conclusión: si tiene un caso de uso crítico de rendimiento (por ejemplo, procesar cientos de cadenas), use el método Regexp. Pero para la mayoría de los casos de uso típicos, vale la pena no tener que preocuparse por los caracteres especiales.

Matthew Crumley
fuente
147
Me sorprendió, ya que esperaría que este método asignara más objetos, creara más basura y, por lo tanto, tomara más tiempo, pero cuando lo probé en un navegador, este método fue consistentemente un 20% más rápido que la respuesta aceptada. Los resultados pueden variar, por supuesto.
MgSam
42
Tenía curiosidad y configuré esto: jsperf.com/replace-all-vs-split-join . Parece que v8 es muy rápido para dividir / unir matrices en comparación con otros motores javascript.
fabi
8
Muy agradable: también lo salva de la posibilidad de malas RegExps al pasar caracteres especiales. Estoy agregando una marca genérica para "buscar esto y reemplazarlo" en una propiedad de objeto, pero me preocupaba si necesitaba reemplazar "." o "}" y olvidé que estaba usando RegEx 3 meses después.
tobriand
99
Y como String.prototype: String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}. Uso: "My string".replaceAll('st', '');produce "My ring"
MacroMan
8
No veo una razón para la advertencia de no usar esto en producción. No es más un truco que escapar de una expresión regular solo porque desea reemplazar múltiples ocurrencias, pero no necesita una expresión regular en primer lugar. Simplemente envuelva este llamado "hack" en una buena replaceAllfunción, y se vuelve tan legible como cualquier otra cosa. Dado que el rendimiento no es malo, no hay razón para evitar esta solución.
youen
4385
str = str.replace(/abc/g, '');

En respuesta al comentario:

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

En respuesta al comentario de Click Upvote , podría simplificarlo aún más:

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(find, 'g'), replace);
}

Nota: Las expresiones regulares contienen caracteres especiales (meta) y, como tal, es peligroso pasar ciegamente un argumento en la findfunción anterior sin procesarlo previamente para escapar de esos caracteres. Esto se trata en la red de desarrolladores de Mozilla 's Guía de JavaScript en las expresiones regulares , donde presentan la siguiente función de utilidad (que ha cambiado al menos dos veces desde esta respuesta fue escrito originalmente, así que asegúrese de comprobar el sitio MDN para las actualizaciones posibles):

function escapeRegExp(string) {
  return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

Entonces, para que la replaceAll()función anterior sea más segura, podría modificarse a lo siguiente si también incluye escapeRegExp:

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
Sean Bright
fuente
44
Las expresiones regulares son la única forma de lograr esto "fuera de la caja" sin implementar su propio método 'replaceAll'. No estoy sugiriendo su uso solo por usarlos.
Sean Bright
10
Esta es mi propia función de este comentario: function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
Haga clic en Upvote el
47
La advertencia principal de la replaceAllimplementación es que no funcionará si findcontiene metacaracteres.
Martin Ender
1
@SeanBright tienes razón. Utilicé su javascript en un código php, así que tuve que agregar una barra invertida adicional para escapar. En el violín tu código es perfecto. Debería haberlo comprobado. Disculpas jsfiddle.net/7y19xyq8
Onimusha
2437

En aras de la exhaustividad, me puse a pensar qué método debería utilizar para hacer esto. Básicamente, hay dos formas de hacer esto, como lo sugieren las otras respuestas en esta página.

Nota: en general, no se recomienda extender los prototipos incorporados en JavaScript. Proporciono como extensiones en el prototipo de cadena simplemente con fines ilustrativos, mostrando diferentes implementaciones de un método estándar hipotético en el Stringprototipo incorporado.


Implementación basada en expresiones regulares

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

Implementación de división y unión (funcional)

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

Sin saber demasiado acerca de cómo funcionan las expresiones regulares detrás de escena en términos de eficiencia, tendí a inclinarme hacia la división y unirme a la implementación en el pasado sin pensar en el rendimiento. Cuando me pregunté cuál era más eficiente y por qué margen, lo usé como una excusa para averiguarlo.

En mi máquina Chrome con Windows 8, la implementación basada en expresiones regulares es la más rápida , con una implementación de división y unión un 53% más lenta . Lo que significa que las expresiones regulares son dos veces más rápidas para la entrada lorem ipsum que utilicé.

Consulte este punto de referencia que ejecuta estas dos implementaciones entre sí.


Como se señala en el comentario a continuación por @ThomasLeduc y otros, podría haber un problema con la implementación basada en expresiones regulares si searchcontiene ciertos caracteres que están reservados como caracteres especiales en expresiones regulares . La implementación supone que la persona que llama escapará de la cadena de antemano o solo pasará cadenas que no tengan los caracteres en la tabla en Expresiones regulares (MDN).

MDN también proporciona una implementación para escapar de nuestras cadenas. Sería bueno si esto también se estandarizara RegExp.escape(str), pero, por desgracia, no existe:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

Podríamos llamar escapeRegExpdentro de nuestra String.prototype.replaceAllimplementación, sin embargo, no estoy seguro de cuánto afectará esto al rendimiento (potencialmente incluso para cadenas para las que no se necesita el escape, como todas las cadenas alfanuméricas).

Cory Gross
fuente
8
En Android 4.1, el método regexp es un 15% más rápido, pero no escapa de la expresión para buscar, por lo que este punto de referencia está incompleto.
andreszs
33
Hay un problema con esta solución, si su cadena de búsqueda parece contener caracteres especiales de una expresión regexp, se interpretarán. Recomiendo la respuesta de @Sandy Unitedwolf.
Thomas Leduc
2
El primero hará esto: 'bla.bla'.replaceAll ('. ',' _ '); "_______". El segundo hará 'bla_bla', que en general es lo que quieres hacer.
RobKohr
1
@ThomasLeduc parece que el problema que mencionó puede solucionarse con lodash => lodash.com/docs/4.17.5#escapeRegExp
Matthew Beck
1
Dejando esto aquí para futuros espectadores que también se preguntan por qué extender el objeto nativo es una mala idea: stackoverflow.com/questions/14034180/…
Ben Cooper
692

El uso de una expresión regular con el gconjunto de banderas reemplazará a todos:

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

Mira aquí también

Adam A
fuente
15
Creo que es un poco tonto, pero la expresión regular global de JS es la única forma de hacer reemplazos múltiples.
Mike
55
bueno, técnicamente puedes recorrer el var sourceTextrecuento de la cantidad de instancias ( numOfInstances) usando substringo dividir y contar la longitud (entre otras estrategias) de thatWhichYouWantToReplaceentonces do for (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');} o incluso más fácil, solo usa un ciclo while ( while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)) pero no veo por qué querrías hágalo de esa manera cuando usarlo /gsea ​​tan fácil y probablemente más eficiente.
Zargold
@ Zargold Desea hacer un bucle para asegurarse de que, incluso después del reemplazo, haya reemplazado todas las instancias, lo cual es un problema bastante común. Vea mi respuesta a continuación stackoverflow.com/a/26089052/87520
SamGoody
109

Aquí hay una función de prototipo de cadena basada en la respuesta aceptada:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

EDITAR

Si tu findva a contener caracteres especiales entonces necesitas escapar de ellos:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

Violín: http://jsfiddle.net/cdbzL/

jesal
fuente
55
Pero, ¿qué findpasa si contiene caracteres como .o $que tienen significados especiales en expresiones regulares?
callum
1
@callum En ese caso, tendría que escapar de su variable de búsqueda (consulte la edición anterior).
Jesús
Jesús, esta es una solución maravillosa para un problema de reemplazo de cadenas que he encontrado, y aparentemente supera la "inmutabilidad" de las cadenas en JavaScript. ¿Podría usted u otra persona explicar cómo esta función prototipo anula la inmutabilidad de las cadenas? Esto hace el trabajo; Solo quiero entender esta pregunta auxiliar que plantea.
Tom
1
@Tom: no supera la inmutabilidad en absoluto: var str = thiscrea una segunda referencia a la cadena inmutable, a la que replacese aplica el método, que a su vez devuelve una nueva cadena inmutable . estas funciones prototipo devuelven una nueva cadena inmutable; de ​​lo contrario, podría escribir someStrVar.replaceAll('o', '0');y someStrVarcambiaría. En su lugar, debe escribir someStrVar = someStrVar.replaceAll('o', '0');<- reasignar para configurar la var para que contenga la nueva cadena inmutable . no hay forma de evitar eso. Prueba en la consola:x = 'foobar'; x.replaceAll('o', '0'); x;
Elias Van Ootegem
87

Actualizar:

Es algo tarde para una actualización, pero dado que me topé con esta pregunta y noté que mi respuesta anterior no es una con la que estoy contento. Dado que la pregunta implicaba reemplazar una sola palabra, es increíble que nadie haya pensado en usar límites de palabras ( \b)

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

Esta es una expresión regular simple que evita reemplazar partes de palabras en la mayoría de los casos. Sin embargo, un guión -todavía se considera un límite de palabras. Por lo tanto, los condicionales se pueden usar en este caso para evitar reemplazar cadenas como cool-cat:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

básicamente, esta pregunta es la misma que la pregunta aquí: Javascript reemplaza "'" con "' '"

@ Mike, revisa la respuesta que di allí ... regexp no es la única forma de reemplazar múltiples ocurrencias de un subsubting, ni mucho menos. ¡Piensa flexible, piensa dividido!

var newText = "the cat looks like a cat".split('cat').join('dog');

Alternativamente, para evitar el reemplazo de partes de palabras, ¡lo que también hará la respuesta aprobada! Puede solucionar este problema utilizando expresiones regulares que son, lo admito, algo más complejas y, como resultado, un poco más lento también:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

La salida es la misma que la respuesta aceptada, sin embargo, usando la expresión / cat / g en esta cadena:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

Vaya, de hecho, esto probablemente no es lo que quieres. ¿Que es entonces? En mi humilde opinión, una expresión regular que solo reemplaza 'cat' condicionalmente. (es decir, no forma parte de una palabra), así:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

Supongo que esto satisface tus necesidades. No es totalmente resistente, por supuesto, pero debería ser suficiente para comenzar. Recomiendo leer un poco más en estas páginas. Esto resultará útil para perfeccionar esta expresión para satisfacer sus necesidades específicas.

http://www.javascriptkit.com/jsref/regexp.shtml

http://www.regular-expressions.info


Adición final:

Dado que esta pregunta aún tiene muchas vistas, pensé que podría agregar un ejemplo de .replaceutilizado con una función de devolución de llamada. En este caso, simplifica drásticamente la expresión y proporciona aún más flexibilidad, como reemplazar con mayúsculas correctas o reemplazar ambas caty catsde una vez:

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar
Elias Van Ootegem
fuente
Creo que la parte interesante adicional debería colocarse en la parte inferior. ps .: Me acabo de dar cuenta de que la mitad de la primera línea está fuera del área, ¡déjenme arreglarlo!
69

Emparejar contra una expresión regular global:

anotherString = someString.replace(/cat/g, 'dog');
scronide
fuente
60

Para reemplazar un solo uso de tiempo:

var res = str.replace('abc', "");

Para reemplazar varias veces, use:

var res = str.replace(/abc/g, "");
Indrajeet Singh
fuente
para que alguien necesite reemplazar \ n, puede hacerlo como:replace(/\n/g, '<br/>')
Phan Van Linh, el
58

Estos son los métodos más comunes y legibles.

var str = "Test abc test test abc test test test abc test test abc"

Método 1:

str = str.replace(/abc/g, "replaced text");

Método 2:

str = str.split("abc").join("replaced text");

Método 3:

str = str.replace(new RegExp("abc", "g"), "replaced text");

Método 4:

while(str.includes("abc")){
    str = str.replace("abc", "replaced text");
}

Salida:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text
Adnan Toky
fuente
44
str = str.replace(/abc/g, '');

O pruebe la función replaceAll desde aquí:

¿Cuáles son los métodos útiles de JavaScript que amplían los objetos integrados?

str = str.replaceAll('abc', ''); OR

var search = 'abc';
str = str.replaceAll(search, '');

EDITAR: Aclaración sobre reemplazar Toda la disponibilidad

El método 'replaceAll' se agrega al prototipo de String. Esto significa que estará disponible para todos los objetos de cadena / literales.

P.ej

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'
SolutionYogi
fuente
2
¿Puedes reescribir la función replaceAll () para aquellos que no usan prototipos?
Haga clic en Upvote el
@ Haga clic en Upvote ... está utilizando un prototipo, es parte de todos los objetos JS. Creo que estás pensando en prototype.js la biblioteca JS.
seth
Seth, una pequeña corrección. Si agrega un método a un prototipo, está disponible para todos los objetos de ese tipo. El método replceAll se agregó al prototipo de cadena y debería funcionar para todos los objetos de cadena.
SolutionYogi
@solutionyogi - Sí, he usado un prototipo (correctamente) antes. Estaba abordando el comentario del OP sobre "no usar prototipo", que supuse que significaba Prototype.js (¿quizás incorrectamente?). Debería haber dicho "un prototipo" ya que estaba tratando de decir que los objetos JavaScript tienen un prototipo. Por lo tanto, el OP ya estaba 'usando prototipo', aunque de manera "indirecta". Indirecto podría ser el término incorrecto para usar aquí, pero estoy cansado, así que mea culpa.
seth
41

El uso RegExpde JavaScript podría hacer el trabajo por usted, simplemente haga algo como el código a continuación, no olvide el /gdespués del cual se destaca para global :

var str ="Test abc test test abc test test test abc test test abc";
str = str.replace(/abc/g, '');

Si piensa en la reutilización, cree una función que lo haga por usted, pero no se recomienda, ya que es solo una función de línea, pero de nuevo, si usa esto en exceso, puede escribir algo como esto:

String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {
  return this.replace(new RegExp(string, 'g'), replaced);
};

y simplemente utilícelo en su código una y otra vez como a continuación:

var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');

Pero como mencioné anteriormente, no hará una gran diferencia en términos de líneas para escribir o rendimiento, solo el almacenamiento en caché de la función puede afectar un rendimiento más rápido en cadenas largas y también una buena práctica del código DRY si desea reutilizar.

Alireza
fuente
40

Digamos que desea reemplazar todo el 'abc' con 'x':

let some_str = 'abc def def lom abc abc def'.split('abc').join('x')
console.log(some_str) //x def def lom x x def

Estaba tratando de pensar en algo más simple que modificar el prototipo de cadena.

Emilio Grisolía
fuente
1
Simple, fácil y probablemente la opción más eficaz: buena respuesta.
machineghost
En realidad, aunque no lo he medido personalmente, dividir / unir suele ser una solución muy eficaz.
machineghost
1
incluso en Chrome, 100% más rápido en Firefox y 50% más lento en IE ...: jsperf.com/replace-regex-split-join
Olivier
37

Usa una expresión regular:

str.replace(/abc/g, '');
Donnie DeBoer
fuente
32

Reemplazar comillas simples:

function JavaScriptEncode(text){
    text = text.replace(/'/g,'&apos;')
    // More encode here if required

    return text;
}
Chris Rosete
fuente
2
¿Cómo puedo cambiar la segunda línea para reemplazar cadenas? Esto no funciona: text = text.replace ('hey', 'hello'); ¿Alguna idea?
Stefan Đorđević
2
Claro Stefan, aquí está el código ... text = text.replace (/ hey / g, 'hola');
Chris Rosete
26

// repítelo hasta que las ocurrencias numéricas lleguen a 0. O simplemente copie / pegue

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }
Raseela
fuente
23
Este método es peligroso, no lo use. Si la cadena de reemplazo contiene la palabra clave de búsqueda, se producirá un bucle infinito. Como mínimo, almacene el resultado de .indexOfen una variable y use esta variable como el segundo parámetro de .indexOf(menos la longitud de la palabra clave, más la longitud de la cadena de reemplazo).
Rob W
Estoy pensando en reemplazar primero el patrón de búsqueda con un char unicode con weired, de eso estamos seguros de que no se usa en la cadena de entrada. Como U + E000 en el área privada. Y luego vuelva a colocarlo en el objetivo. He construido eso aquí. . No estoy seguro si esa es una buena idea.
Lux
26
str = str.replace(new RegExp("abc", 'g'), "");

funcionó mejor para mí que las respuestas anteriores. por lo que new RegExp("abc", 'g')crea una expresión regular coincide con lo que toda ocurrencia ( 'g'bandera) del texto ( "abc"). La segunda parte es a lo que se reemplaza, en su caso cadena vacía ( ""). stres la cadena, y tenemos que anularla, ya que replace(...)solo devuelve el resultado, pero no anula. En algunos casos, es posible que desee usar eso.

csomakk
fuente
Si bien este fragmento de código puede ser la solución, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
yivi
Si, tienes razón. adicional. También editado para responder a la pregunta original :)
csomakk
Nota: g flag en regex significa que es una bandera global que coincidirá con todas las ocurrencias
firstpostcommenter
25

Esta es la versión más rápida que no usa expresiones regulares .

Jsperf revisado

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

Es casi el doble de rápido que el método de división y unión.

Como se señala en un comentario aquí, esto no funcionará si su omitvariable contiene place, como en:, replaceAll("string", "s", "ss")porque siempre podrá reemplazar otra aparición de la palabra.

¡Hay otro jsperf con variantes en mi reemplazo recursivo que va aún más rápido ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • Actualización 27 de julio de 2017: Parece que RegExp ahora tiene el rendimiento más rápido en el recientemente lanzado Chrome 59.
Cole Lawrence
fuente
Me encantó tu solución ... desearía poder darte +10 pero aquí está mi +1. Creo que puede almacenar el índice de la subcadena que se reemplazó y saltar al siguiente si se encuentra una coincidencia en un índice inferior para evitar ese problema de bucle infinito. No puedo comentar sobre el rendimiento porque no lo probé, pero eso es solo mis 2 centavos en esta pieza de excelencia.
Fr0zenFyr
@ fr0zenfyr si desea verificar si la omisión está en su lugar (para evitar el bucle infinito), puede hacer un condicional como if(place.replace(omit) === omit) {Sin coincidencia, por lo que es seguro usar Reemplazar bucle de } else {coincidencia, así que use un método diferente como dividir y unir}
Cole Lawrence
Hmm ... pero, ¿qué sentido tiene combinar dos soluciones? No soy fan de todos modos un split / join enfoque de todos modos .. gracias por el consejo ..
Fr0zenFyr
@ Fr0zenFyr Creo que el propósito de combinar las dos soluciones sería recurrir a un método más lento si no puede usar el más rápido (cuando el ciclo sería infinito, por ejemplo). Por lo tanto, sería una protección segura para garantizar la funcionalidad con eficiencia, pero sin posibilidad de falla.
Cole Lawrence
@momomo ¿qué tan defectuoso?
SandRock
24

Actuación

Hoy 27.12.2019 realizo pruebas en macOS v10.13.6 (High Sierra) para las soluciones elegidas.

Conclusiones

  • La str.replace(/abc/g, '');( C ) es una buena solución rápida para varios navegadores para todas las cadenas.
  • Las soluciones basadas en split-join( A, B ) o replace( C, D ) son rápidas
  • Las soluciones basadas en while( E, F, G, H ) son lentas, generalmente ~ 4 veces más lento para cadenas pequeñas y aproximadamente ~ 3000 veces (!) Más lento para cadenas largas
  • Las soluciones de recurrencia ( RA, RB ) son lentas y no funcionan para cadenas largas

También creo mi propia solución. Parece que actualmente es el más corto que hace el trabajo de preguntas:

str.split`abc`.join``

Detalles

Las pruebas se realizaron en Chrome 79.0, Safari 13.0.4 y Firefox 71.0 (64 bits). Las pruebas RAy el RBuso de recursividad. Resultados

Ingrese la descripción de la imagen aquí

Cadena corta - 55 caracteres

Puede ejecutar pruebas en su máquina AQUÍ . Resultados para Chrome:

Ingrese la descripción de la imagen aquí

Cadena larga: 275 000 caracteres.

Las soluciones recursivas RA y RB dan

RangeError: se excedió el tamaño máximo de la pila de llamadas

Para los personajes de 1M incluso rompen Chrome

ingrese la descripción de la imagen aquí

Intento realizar pruebas para 1M caracteres para otras soluciones, pero E, F, G, H toma tanto tiempo que el navegador me pide que rompa el script para reducir la cadena de prueba a 275K caracteres. Puede ejecutar pruebas en su máquina AQUÍ . Resultados para Chrome

ingrese la descripción de la imagen aquí

Código utilizado en pruebas

Kamil Kiełczewski
fuente
1
¡Ahora esta es una respuesta profunda! ¡Muchas gracias! Aunque, lo que tengo curiosidad es por qué la sintaxis "nuevo RegExp (...)" ofrece una gran mejora.
Márk Gergely Dolinka
21

Si lo que desea encontrar ya está en una cadena, y no tiene a mano un escáner de expresiones regulares, puede usar join / split:

    function replaceMulti(haystack, needle, replacement)
    {
        return haystack.split(needle).join(replacement);
    }

    someString = 'the cat looks like a cat';
    console.log(replaceMulti(someString, 'cat', 'dog'));

rakslice
fuente
¡Gracias! Esta solución funciona perfectamente para mi problema :)
xero399
19
function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}
Tim Rivoli
fuente
Me pregunto qué tan bien funciona ... la subcadena es nativa o camina sobre la matriz de caracteres para crear los nuevos personajes.
mmm
16

Me gusta este método (se ve un poco más limpio):

text = text.replace(new RegExp("cat","g"), "dog"); 
Owen
fuente
1
De acuerdo, ¿cómo escapas de la cadena para usarla como patrón regex?
rakslice
No lo hago, solo lo uso para texto sin formato
Owen
15

La forma más simple de hacerlo sin usar expresiones regulares es dividir y unir como el código aquí:

var str = "Test abc test test abc test test test abc test test abc";
str.split('abc').join('')
sajadre
fuente
13
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);

http://jsfiddle.net/ANHR9/

pkdkk
fuente
¿cuál fue el punto de un violín que sólo contiene la misma Javascript
JGallardo
13
while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}
zdennis
fuente
13

Si la cadena contiene un patrón similar abccc, puede usar esto:

str.replace(/abc(\s|$)/g, "")
mostafa elmadany
fuente
13

Las respuestas anteriores son demasiado complicadas. Simplemente use la función de reemplazo de esta manera:

str.replace(/your_regex_pattern/g, replacement_string);

Ejemplo:

var str = "Test abc test test abc test test test abc test test abc";

var res = str.replace(/[abc]+/g, "");

console.log(res);

Negro
fuente
10

Si intenta asegurarse de que la cadena que está buscando no existirá incluso después del reemplazo, debe usar un bucle.

Por ejemplo:

var str = 'test aabcbc';
str = str.replace(/abc/g, '');

Cuando termine, ¡todavía tendrá 'test abc'!

El bucle más simple para resolver esto sería:

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

Pero eso ejecuta el reemplazo dos veces para cada ciclo. Quizás (en riesgo de ser rechazado) que pueda combinarse para una forma ligeramente más eficiente pero menos legible:

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

Esto puede ser particularmente útil cuando se buscan cadenas duplicadas.
Por ejemplo, si tenemos 'a ,,, b' y deseamos eliminar todas las comas duplicadas.
[En ese caso, uno podría hacer .replace (/, + / g, ','), pero en algún momento la expresión regular se vuelve compleja y lo suficientemente lenta como para hacer un bucle.]

SamGoody
fuente
10

Aunque la gente ha mencionado el uso de expresiones regulares, hay un mejor enfoque si desea reemplazar el texto independientemente del caso del texto. Como mayúsculas o minúsculas. Use la siguiente sintaxis

//Consider below example
originalString.replace(/stringToBeReplaced/gi, '');

//Output will be all the occurrences removed irrespective of casing.

Puede consultar el ejemplo detallado aquí .

Código Cheezy
fuente
del sitio de ejemplo: "/ toBeReplacedString / gi es la expresión regular que necesita usar. Aquí g representa una coincidencia global e i no distingue entre mayúsculas y minúsculas. Por defecto, la expresión regular distingue mayúsculas de minúsculas"
alikuli
8

Simplemente puede usar el siguiente método

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};
tk_
fuente
7

Solo agrega /g

document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');

a

// Replace 'hello' string with /hello/g regular expression.
document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');

/g significa global

Reza Fahmi
fuente