Ersetzen Sie mehrere Zeichenfolgen durch mehrere andere Zeichenfolgen


213

Ich versuche, mehrere Wörter in einer Zeichenfolge durch mehrere andere Wörter zu ersetzen. Die Zeichenfolge lautet "Ich habe eine Katze, einen Hund und eine Ziege."

Dies erzeugt jedoch nicht "Ich habe einen Hund, eine Ziege und eine Katze", sondern "Ich habe eine Katze, eine Katze und eine Katze". Ist es in JavaScript möglich, mehrere Zeichenfolgen gleichzeitig durch mehrere andere Zeichenfolgen zu ersetzen, damit das richtige Ergebnis erzielt wird?

var str = "I have a cat, a dog, and a goat.";
str = str.replace(/cat/gi, "dog");
str = str.replace(/dog/gi, "goat");
str = str.replace(/goat/gi, "cat");

//this produces "I have a cat, a cat, and a cat"
//but I wanted to produce the string "I have a dog, a goat, and a cat".

Ich möchte mehrere Wörter in einer Zeichenfolge durch mehrere andere Wörter ersetzen, ohne bereits ersetzte Wörter zu ersetzen.
Anderson Green

Ich habe eine andere Frage, was ist, wenn ich nicht weiß, dass der Benutzer Katze, Hund oder Ziege eingeben wird (dies kommt zufällig), aber wann immer dieses Wort kommt, muss ich es durch "Tier" ersetzen. wie man dieses Szenario bekommt
Prasanna Sasne

Antworten:


445

Spezifische Lösung

Sie können eine Funktion verwenden, um jede zu ersetzen.

var str = "I have a cat, a dog, and a goat.";
var mapObj = {
   cat:"dog",
   dog:"goat",
   goat:"cat"
};
str = str.replace(/cat|dog|goat/gi, function(matched){
  return mapObj[matched];
});

jsfiddle Beispiel

Verallgemeinern

Wenn Sie den regulären Ausdruck dynamisch beibehalten und der Karte nur zukünftige Austausche hinzufügen möchten, können Sie dies tun

new RegExp(Object.keys(mapObj).join("|"),"gi"); 

um den regulären Ausdruck zu erzeugen. Dann würde es so aussehen

var mapObj = {cat:"dog",dog:"goat",goat:"cat"};

var re = new RegExp(Object.keys(mapObj).join("|"),"gi");
str = str.replace(re, function(matched){
  return mapObj[matched];
});

Und um weitere Ersetzungen hinzuzufügen oder zu ändern, können Sie einfach die Karte bearbeiten. 

Geige mit dynamischem Regex

Wiederverwendbar machen

Wenn Sie möchten, dass dies ein allgemeines Muster ist, können Sie dies auf eine Funktion wie diese ziehen

function replaceAll(str,mapObj){
    var re = new RegExp(Object.keys(mapObj).join("|"),"gi");

    return str.replace(re, function(matched){
        return mapObj[matched.toLowerCase()];
    });
}

Dann könnten Sie einfach die str und eine Zuordnung der gewünschten Ersetzungen an die Funktion übergeben und die transformierte Zeichenfolge zurückgeben.

Geige mit der Funktion

Um sicherzustellen, dass Object.keys in älteren Browsern funktioniert, fügen Sie eine Polyfüllung hinzu, z. B. aus MDN oder Es5 .


4
Ich bin mir nicht sicher, ob ich diese Funktion verwenden könnte, um alle Arten von Zeichenfolgen zu ersetzen, da die Zeichen, die in JavaScript-Zeichenfolgen zulässig sind, nicht mit den Zeichen übereinstimmen, die in JavaScript-Bezeichnern zulässig sind (z. B. die hier verwendeten Schlüssel). .
Anderson Green

2
Sie können eine beliebige Zeichenfolge als Javascript-Eigenschaft verwenden. Sollte keine Rolle spielen. Sie können die .Notation einfach nicht mit all diesen Eigenschaften verwenden. Die Notation in Klammern funktioniert mit jeder Zeichenfolge.
Ben McCormick

2
Es funktioniert in der Tat großartig. Ich verwende diese Lösung (die "spezifische") erfolgreich, um englische Notationen in europäische (24.973,56 bis 24.973.56) zu ändern, indem ich map={'.': ',', ',': '.'}und Regex verwende /\.|,/g.
Sygmoral

5
Ich liebe diese Lösung, aber ich musste sie ersetzen return mapObj[matched.toLowerCase()];, return mapObj[matched];da ich Groß- und Kleinschreibung verwende mapObj.
Michal Moravcik

2
Möglicherweise möchten Sie die Schlüssel für den regulären Ausdruck maskieren : Object.keys(mapObj).map(key => key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|'). Inspiriert von dieser Antwort
Robsch

9

Dies entspricht möglicherweise nicht genau Ihren Anforderungen in diesem Fall, aber ich habe festgestellt, dass dies als allgemeine Lösung eine nützliche Möglichkeit ist, mehrere Parameter in Zeichenfolgen zu ersetzen. Es werden alle Instanzen der Parameter ersetzt, unabhängig davon, wie oft auf sie verwiesen wird:

String.prototype.fmt = function (hash) {
        var string = this, key; for (key in hash) string = string.replace(new RegExp('\\{' + key + '\\}', 'gm'), hash[key]); return string
}

Sie würden es wie folgt aufrufen:

var person = '{title} {first} {last}'.fmt({ title: 'Agent', first: 'Jack', last: 'Bauer' });
// person = 'Agent Jack Bauer'

8

Verwenden Sie nummerierte Elemente, um ein erneutes Ersetzen zu verhindern. z.B

let str = "I have a %1, a %2, and a %3";
let pets = ["dog","cat", "goat"];

dann

str.replace(/%(\d+)/g, (_, n) => pets[+n-1])

So funktioniert es: -% \ d + findet die Zahlen, die nach einem% stehen. Die Klammern erfassen die Nummer.

Diese Zahl (als Zeichenfolge) ist der zweite Parameter n für die Lambda-Funktion.

Das + n-1 konvertiert die Zeichenfolge in die Zahl, dann wird 1 subtrahiert, um das Haustierarray zu indizieren.

Die% -Zahl wird dann durch die Zeichenfolge am Array-Index ersetzt.

Das / g bewirkt, dass die Lambda-Funktion wiederholt mit jeder Nummer aufgerufen wird, die dann durch eine Zeichenfolge aus dem Array ersetzt wird.

In modernem JavaScript: -

replace_n=(str,...ns)=>str.replace(/%(\d+)/g,(_,n)=>ns[n-1])

Interessant. Können Sie die Logik in der Ersetzungsfunktion erklären?
Eric Hepperle - CodeSlayer2010

5

Das hat bei mir funktioniert:

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

function replaceAll(str, map){
    for(key in map){
        str = str.replaceAll(key, map[key]);
    }
    return str;
}

//testing...
var str = "bat, ball, cat";
var map = {
    'bat' : 'foo',
    'ball' : 'boo',
    'cat' : 'bar'
};
var new = replaceAll(str, map);
//result: "foo, boo, bar"


Funktioniert nicht, wenn die Zeichenfolge Regex-Zeichen enthält.
Roemer

Über "Nicht verlängern ...": Ich habe meinen String erweitert, um zwei Strings auf Gleichheit zu vergleichen, wobei die Groß- und Kleinschreibung nicht berücksichtigt wird. Diese Funktionalität wird nicht von String bereitgestellt, kann aber eines Tages dazu führen, dass meine Apps nicht mehr funktionieren. Gibt es eine Möglichkeit, einen String "unterzuordnen" oder zu "erweitern", um eine solche Funktion sicher einzuschließen, oder sollte ich einfach eine neue Funktion mit zwei Argumenten als Teil meiner App-Bibliothek definieren?
David Spector

4

using Array.prototype.reduce () :

const arrayOfObjects = [
  { plants: 'men' },
  { smart:'dumb' },
  { peace: 'war' }
]
const sentence = 'plants are smart'

arrayOfObjects.reduce(
  (f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence
)

// as a reusable function
const replaceManyStr = (obj, sentence) => obj.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence)

const result = replaceManyStr(arrayOfObjects , sentence1)

Beispiel

// /////////////    1. replacing using reduce and objects

// arrayOfObjects.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence)

// replaces the key in object with its value if found in the sentence
// doesn't break if words aren't found

// Example

const arrayOfObjects = [
  { plants: 'men' },
  { smart:'dumb' },
  { peace: 'war' }
]
const sentence1 = 'plants are smart'
const result1 = arrayOfObjects.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence1)

console.log(result1)

// result1: 
// men are dumb


// Extra: string insertion python style with an array of words and indexes

// usage

// arrayOfWords.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence)

// where arrayOfWords has words you want to insert in sentence

// Example

// replaces as many words in the sentence as are defined in the arrayOfWords
// use python type {0}, {1} etc notation

// five to replace
const sentence2 = '{0} is {1} and {2} are {3} every {5}'

// but four in array? doesn't break
const words2 = ['man','dumb','plants','smart']

// what happens ?
const result2 = words2.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence2)

console.log(result2)

// result2: 
// man is dumb and plants are smart every {5}

// replaces as many words as are defined in the array
// three to replace
const sentence3 = '{0} is {1} and {2}'

// but five in array
const words3 = ['man','dumb','plant','smart']

// what happens ? doesn't break
const result3 = words3.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence3)

console.log(result3)

// result3: 
// man is dumb and plants


Beste Antwort. Aber gibt es einen Grund, ${f}anstelle von f den akkumulierten Wert zu verwenden?
David Spector

1
Wenn Sie möchten, dass ALLE angegebenen Zeichenfolgen ersetzt werden, nicht nur die erste, fügen Sie das g-Flag hinzu: "const result1 = arrayOfObjects.reduce ((f, s) => ${f}.replace (new RegExp (Object.keys (s) [) 0], 'g'), s [Object.keys (s) [0]]), Satz 1) "
David Spector

2

Nur für den Fall, dass sich jemand fragt, warum die Lösung des Originalplakats nicht funktioniert:

var str = "I have a cat, a dog, and a goat.";

str = str.replace(/cat/gi, "dog");
// now str = "I have a dog, a dog, and a goat."

str = str.replace(/dog/gi, "goat");
// now str = "I have a goat, a goat, and a goat."

str = str.replace(/goat/gi, "cat");
// now str = "I have a cat, a cat, and a cat."

ha ha ... gut analysiert ... thumbsup
Deepa MG

1

Benutzer reguläre Funktion, um das zu ersetzende Muster zu definieren und dann die Ersetzungsfunktion zu verwenden, um an der Eingabezeichenfolge zu arbeiten.

var i = new RegExp('"{','g'),
    j = new RegExp('}"','g'),
    k = data.replace(i,'{').replace(j,'}');

Wenn Sie nicht wissen, überspringen Sie, aber sagen Sie nicht, dass es die falsche Antwort ist. Mein Fall "{" a ": 1," b ": 2}" ist so, dass ich den obigen Weg ersetzt habe. Wenn es anderen hilft, wenn sie für andere wollen, ist die Antwort nicht nur für Sie. @ Carr
KARTHIKEYAN.A

Wieder haben Sie gerade eine bedeutungslose Antwort gegeben. Was Sie tun, ist, dass der Fragesteller bereits in der Frage tun kann. Diese Antwort wird die Leute irreführen, dass sie vielleicht neu denken und das RegExpObjekt verwenden, um das Problem zu lösen
Carr

In diesem Fall haben Sie immer noch das gleiche Problem wie die Frage des Fragestellers, wenn Sie dies tunvar i = new RegExp('}','g'), j = new RegExp('{','g'), k = data.replace(i,'{').replace(j,'}');
Carr

1

Mit meinem einmaligen Ersatzpaket können Sie Folgendes tun:

const replaceOnce = require('replace-once')

var str = 'I have a cat, a dog, and a goat.'
var find = ['cat', 'dog', 'goat']
var replace = ['dog', 'goat', 'cat']
replaceOnce(str, find, replace, 'gi')
//=> 'I have a dog, a goat, and a cat.'

Dieses Paket ist unglaublich :) Funktioniert genau wie ich erwartet hatte
Vishnu Prassad

1
    var str = "I have a cat, a dog, and a goat.";

    str = str.replace(/goat/i, "cat");
    // now str = "I have a cat, a dog, and a cat."

    str = str.replace(/dog/i, "goat");
    // now str = "I have a cat, a goat, and a cat."

    str = str.replace(/cat/i, "dog");
    // now str = "I have a dog, a goat, and a cat."

3
Die OP fragte : „Ist es möglich , mehrere Strings mit mehreren anderen Saiten zu ersetzen zugleich “. Dies sind drei separate Schritte.
LittleBobbyTables - Au Revoir

1

Sie können Zeichenfolgen mithilfe von Trennzeichen suchen und ersetzen.

var obj = {
  'firstname': 'John',
  'lastname': 'Doe'
}

var text = "My firstname is {firstname} and my lastname is {lastname}"

console.log(mutliStringReplace(obj,text))

function mutliStringReplace(object, string) {
      var val = string
      var entries = Object.entries(object);
      entries.forEach((para)=> {
          var find = '{' + para[0] + '}'
          var regExp = new RegExp(find,'g')
       val = val.replace(regExp, para[1])
    })
  return val;
}


0
String.prototype.replaceSome = function() {
    var replaceWith = Array.prototype.pop.apply(arguments),
        i = 0,
        r = this,
        l = arguments.length;
    for (;i<l;i++) {
        r = r.replace(arguments[i],replaceWith);
    }
    return r;
}

/ * replaceEinige Methode für Zeichenfolgen, für die so viele Argumente benötigt werden, wie wir möchten, und ersetzt sie alle durch das letzte Argument, das wir angegeben haben. 2013 CopyRights gespeichert für: Max Ahmed Dies ist ein Beispiel:

var string = "[hello i want to 'replace x' with eat]";
var replaced = string.replaceSome("]","[","'replace x' with","");
document.write(string + "<br>" + replaced); // returns hello i want to eat (without brackets)

* /

jsFiddle: http://jsfiddle.net/CPj89/


0
<!DOCTYPE html>
<html>
<body>



<p id="demo">Mr Blue 
has a           blue house and a blue car.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction() {
    var str = document.getElementById("demo").innerHTML;
    var res = str.replace(/\n| |car/gi, function myFunction(x){

if(x=='\n'){return x='<br>';}
if(x==' '){return x='&nbsp';}
if(x=='car'){return x='BMW'}
else{return x;}//must need



});

    document.getElementById("demo").innerHTML = res;
}
</script>

</body>
</html>

0

Ich habe dieses npm-Paket stringinject https://www.npmjs.com/package/stringinject geschrieben , mit dem Sie Folgendes tun können

var string = stringInject("this is a {0} string for {1}", ["test", "stringInject"]);

Dadurch werden {0} und {1} durch die Array-Elemente ersetzt und die folgende Zeichenfolge zurückgegeben

"this is a test string for stringInject"

oder Sie können Platzhalter durch Objektschlüssel und Werte wie folgt ersetzen:

var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });

"My username is tjcafferkey on Github" 

0

Sie können zu diesem Zweck https://www.npmjs.com/package/union-replacer verwenden. Es handelt sich im Grunde genommen um ein string.replace(regexp, ...)Gegenstück, bei dem mehrere Ersetzungen in einem Durchgang erfolgen können, während die volle Leistung von erhalten bleibt string.replace(...).

Offenlegung: Ich bin der Autor. Die Bibliothek wurde entwickelt, um komplexere vom Benutzer konfigurierbare Ersetzungen zu unterstützen. Sie behandelt alle problematischen Dinge wie Erfassungsgruppen, Rückreferenzen und Ersetzen von Rückruffunktionen.

Die oben genannten Lösungen sind jedoch gut genug, um die Saiten exakt zu ersetzen.


-1

Ich habe @BenMcCormicks ein bisschen erweitert. Er arbeitete für normale Saiten, aber nicht, wenn ich Charakteren oder Platzhaltern entkommen war. Folgendes habe ich getan

str = "[curl] 6: blah blah 234433 blah blah";
mapObj = {'\\[curl] *': '', '\\d: *': ''};


function replaceAll (str, mapObj) {

    var arr = Object.keys(mapObj),
        re;

    $.each(arr, function (key, value) {
        re = new RegExp(value, "g");
        str = str.replace(re, function (matched) {
            return mapObj[value];
        });
    });

    return str;

}
replaceAll(str, mapObj)

gibt "bla bla 234433 bla bla" zurück

Auf diese Weise stimmt es mit dem Schlüssel in mapObj überein und nicht mit dem übereinstimmenden Wort '


// wertlos: replaceAll ("Ich habe eine Katze, einen Hund und eine Ziege.", {Katze: "Hund", Hund: "Ziege", Ziege: "Katze"}) // produziert: "Ich habe eine Katze , eine Katze und eine Katze. "
Devon

-3

Lösung mit Jquery (zuerst diese Datei einschließen): Ersetzen Sie mehrere Zeichenfolgen durch mehrere andere Zeichenfolgen:

var replacetext = {
    "abc": "123",
    "def": "456"
    "ghi": "789"
};

$.each(replacetext, function(txtorig, txtnew) {
    $(".eng-to-urd").each(function() {
        $(this).text($(this).text().replace(txtorig, txtnew));
    });
});

Benötigt diese Lösung JQuery?
Anderson Green

Javascript-Tag in Frage hinzugefügt, und JQuery ist eine Bibliothek von Javascript.
Supermodel

2
@Super javascript tag added in question, and jquery is a libarary of javascript.Hmmm, diese Logik ist ausgeschaltet, es sollte umgekehrt sein und auch nur ein Kopf hoch - von Javascript-Tag-Informationen: " Sofern kein anderes Tag für ein Framework / eine Bibliothek enthalten ist, wird eine reine JavaScript-Antwort erwartet. "
Traxo

@Anderson Green, ja, für das obige Skript wird eine Abfrage benötigt.
Super Model

@ Traxo, in den meisten Webanwendungen verwenden wir Framework (Bootstrap / Google-Material). Jquery ist in allen modernen Frameworks enthalten. Daher ist jquery ein notwendiges Element für Webanwendungen.
Super Model
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.