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 abc
en la cadena de arriba.
¿Cómo puedo reemplazar todas las ocurrencias?
javascript
string
replace
Haga clic en Upvote
fuente
fuente
aba
inababa
conca
, ¿qué resultado espera?caba
?abca
?cca
?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.replaceAll
reemplaza 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.replaceAll
genera una excepción ”Respuestas:
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
El patrón general es
Esto solía ser más rápido en algunos casos que usar
replaceAll
y 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.
fuente
String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}
. Uso:"My string".replaceAll('st', '');
produce "My ring"replaceAll
funció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.En respuesta al comentario:
En respuesta al comentario de Click Upvote , podría simplificarlo aún más:
Nota: Las expresiones regulares contienen caracteres especiales (meta) y, como tal, es peligroso pasar ciegamente un argumento en la
find
funció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):Entonces, para que la
replaceAll()
función anterior sea más segura, podría modificarse a lo siguiente si también incluyeescapeRegExp
:fuente
function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
replaceAll
implementación es que no funcionará sifind
contiene metacaracteres.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
String
prototipo incorporado.Implementación basada en expresiones regulares
Implementación de división y unión (funcional)
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
search
contiene 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:Podríamos llamar
escapeRegExp
dentro de nuestraString.prototype.replaceAll
implementació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).fuente
El uso de una expresión regular con el
g
conjunto de banderas reemplazará a todos:Mira aquí también
fuente
var sourceText
recuento de la cantidad de instancias (numOfInstances
) usandosubstring
o dividir y contar la longitud (entre otras estrategias) dethatWhichYouWantToReplace
entonces dofor (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/g
sea tan fácil y probablemente más eficiente.Aquí hay una función de prototipo de cadena basada en la respuesta aceptada:
EDITAR
Si tu
find
va a contener caracteres especiales entonces necesitas escapar de ellos:Violín: http://jsfiddle.net/cdbzL/
fuente
find
pasa si contiene caracteres como.
o$
que tienen significados especiales en expresiones regulares?var str = this
crea una segunda referencia a la cadena inmutable, a la quereplace
se 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 escribirsomeStrVar.replaceAll('o', '0');
ysomeStrVar
cambiaría. En su lugar, debe escribirsomeStrVar = 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;
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
)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 comocool-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!
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:
La salida es la misma que la respuesta aceptada, sin embargo, usando la expresión / cat / g en esta cadena:
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í:
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
.replace
utilizado 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 ambascat
ycats
de una vez:fuente
Emparejar contra una expresión regular global:
fuente
Para reemplazar un solo uso de tiempo:
Para reemplazar varias veces, use:
fuente
replace(/\n/g, '<br/>')
Estos son los métodos más comunes y legibles.
Método 1:
Método 2:
Método 3:
Método 4:
Salida:
fuente
O pruebe la función replaceAll desde aquí:
¿Cuáles son los métodos útiles de JavaScript que amplían los objetos integrados?
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
fuente
El uso
RegExp
de JavaScript podría hacer el trabajo por usted, simplemente haga algo como el código a continuación, no olvide el/g
después del cual se destaca para global :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:
y simplemente utilícelo en su código una y otra vez como a continuación:
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.
fuente
Digamos que desea reemplazar todo el 'abc' con 'x':
Estaba tratando de pensar en algo más simple que modificar el prototipo de cadena.
fuente
Usa una expresión regular:
fuente
Reemplazar comillas simples:
fuente
// repítelo hasta que las ocurrencias numéricas lleguen a 0. O simplemente copie / pegue
fuente
.indexOf
en 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).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 (""
).str
es la cadena, y tenemos que anularla, ya quereplace(...)
solo devuelve el resultado, pero no anula. En algunos casos, es posible que desee usar eso.fuente
Esta es la versión más rápida que no usa expresiones regulares .
Jsperf revisado
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
omit
variable contieneplace
, 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 )!
fuente
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}
Actuación
Hoy 27.12.2019 realizo pruebas en macOS v10.13.6 (High Sierra) para las soluciones elegidas.
Conclusiones
str.replace(/abc/g, '');
( C ) es una buena solución rápida para varios navegadores para todas las cadenas.split-join
( A, B ) oreplace
( C, D ) son rápidaswhile
( 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 largasTambién creo mi propia solución. Parece que actualmente es el más corto que hace el trabajo de preguntas:
Mostrar fragmento de código
Detalles
Las pruebas se realizaron en Chrome 79.0, Safari 13.0.4 y Firefox 71.0 (64 bits). Las pruebas
RA
y elRB
uso de recursividad. ResultadosCadena corta - 55 caracteres
Puede ejecutar pruebas en su máquina AQUÍ . Resultados para Chrome:
Cadena larga: 275 000 caracteres.
Las soluciones recursivas RA y RB dan
Para los personajes de 1M incluso rompen Chrome
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
Código utilizado en pruebas
Mostrar fragmento de código
fuente
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:
fuente
fuente
Me gusta este método (se ve un poco más limpio):
fuente
La forma más simple de hacerlo sin usar expresiones regulares es dividir y unir como el código aquí:
fuente
http://jsfiddle.net/ANHR9/
fuente
fuente
Si la cadena contiene un patrón similar
abccc
, puede usar esto:fuente
Las respuestas anteriores son demasiado complicadas. Simplemente use la función de reemplazo de esta manera:
Ejemplo:
fuente
Si intenta asegurarse de que la cadena que está buscando no existirá incluso después del reemplazo, debe usar un bucle.
Por ejemplo:
Cuando termine, ¡todavía tendrá 'test abc'!
El bucle más simple para resolver esto sería:
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:
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.]
fuente
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
Puede consultar el ejemplo detallado aquí .
fuente
Simplemente puede usar el siguiente método
fuente
Solo agrega
/g
a
/g
significa globalfuente