Ganti beberapa string dengan beberapa string lainnya

213

Saya mencoba mengganti beberapa kata dalam sebuah string dengan banyak kata lain. Tali itu adalah "Saya punya kucing, anjing, dan seekor kambing."

Namun, ini tidak menghasilkan "Saya punya anjing, kambing, dan kucing", tetapi malah menghasilkan "Saya punya kucing, kucing, dan kucing". Apakah mungkin untuk mengganti beberapa string dengan beberapa string lainnya secara bersamaan dalam JavaScript, sehingga hasil yang benar akan dihasilkan?

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".
Anderson Green
sumber
Saya ingin mengganti beberapa kata dalam sebuah string dengan banyak kata lain, tanpa mengganti kata-kata yang sudah diganti.
Anderson Green
Saya punya beberapa pertanyaan yang berbeda, bagaimana jika saya tidak tahu pengguna akan memasukkan kucing atau anjing atau kambing (ini datang secara acak) tetapi setiap kali kata ini akan datang saya harus mengganti dengan katakanlah 'binatang'. bagaimana cara mendapatkan skenario ini
Prasanna Sasne

Jawaban:

445

Solusi spesifik

Anda dapat menggunakan fungsi untuk mengganti masing-masing.

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];
});

contoh jsfiddle

Generalisasi itu

Jika Anda ingin mempertahankan regex secara dinamis dan menambahkan pertukaran di masa mendatang ke peta, Anda bisa melakukan ini

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

untuk menghasilkan regex. Jadi akan terlihat seperti ini

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];
});

Dan untuk menambah atau mengubah penggantian lagi, Anda cukup mengedit peta. 

biola dengan regex dinamis

Membuatnya dapat digunakan kembali

Jika Anda ingin ini menjadi pola umum, Anda bisa menariknya ke fungsi seperti ini

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

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

Jadi Anda bisa melewati str dan peta penggantian yang Anda inginkan ke fungsi dan itu akan mengembalikan string yang diubah.

bermain-main dengan fungsi

Untuk memastikan Object.keys berfungsi di browser lama, tambahkan mis polyfill dari MDN atau Es5 .

Ben McCormick
sumber
4
Saya tidak yakin apakah saya bisa menggunakan fungsi ini untuk mengganti semua jenis string, karena karakter yang diizinkan dalam string JavaScript tidak sama dengan karakter yang diizinkan dalam pengidentifikasi JavaScript (seperti kunci yang digunakan di sini) .
Anderson Green
2
Anda dapat menggunakan string arbitrer sebagai properti javascript. Seharusnya tidak masalah. Anda tidak bisa menggunakan .notasi dengan semua properti seperti itu. Notasi kurung berfungsi dengan string apa pun.
Ben McCormick
2
Ini memang berhasil. Saya berhasil menggunakan solusi ini (yang 'spesifik') untuk mengubah notasi angka bahasa Inggris menjadi notasi Eropa (24.973,56 menjadi 24.973.56), menggunakan map={'.': ',', ',': '.'}dan regex /\.|,/g.
Sygmoral
5
Saya suka solusi ini tapi aku harus mengganti return mapObj[matched.toLowerCase()];hanya return mapObj[matched];karena saya menggunakan kasus tombol sensitif di mapObj.
Michal Moravcik
2
Anda mungkin ingin melarikan diri kunci untuk ekspresi reguler: Object.keys(mapObj).map(key => key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join('|'). Terinspirasi oleh jawaban ini
robsch
9

Ini mungkin tidak memenuhi kebutuhan persis Anda dalam contoh ini, tetapi saya telah menemukan ini cara yang berguna untuk mengganti beberapa parameter dalam string, sebagai solusi umum. Ini akan menggantikan semua instance parameter, tidak peduli berapa kali direferensikan:

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

Anda akan memohonnya sebagai berikut:

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

Gunakan item bernomor untuk mencegah penggantian lagi. misalnya

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

kemudian

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

Cara kerjanya: -% \ d + menemukan angka yang muncul setelah%. Kurung menangkap nomor tersebut.

Angka ini (sebagai string) adalah parameter ke-2, n, untuk fungsi lambda.

+ N-1 mengonversi string menjadi angka kemudian 1 dikurangi untuk mengindeks array binatang peliharaan.

Angka% kemudian diganti dengan string pada indeks array.

/ G menyebabkan fungsi lambda dipanggil berulang kali dengan setiap angka yang kemudian diganti dengan string dari array.

Dalam JavaScript modern: -

replace_n=(str,...ns)=>str.replace(/%(\d+)/g,(_,n)=>ns[n-1])
Quentin 2
sumber
Menarik. Bisakah Anda menjelaskan logika dalam fungsi ganti?
Eric Hepperle - CodeSlayer2010
5

Ini bekerja untuk saya:

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"
João Paulo
sumber
Tidak berfungsi jika string berisi karakter regex.
Roemer
Tentang "jangan memperpanjang ...": Saya memperluas String saya untuk membandingkan dua string untuk kesetaraan, case-insensitive. Fungsi ini tidak disediakan oleh String, tetapi mungkin suatu hari nanti, yang dapat menyebabkan aplikasi saya rusak. Apakah ada cara untuk "subkelas" atau "memperluas" String untuk memasukkan fungsi seperti itu dengan aman, atau haruskah saya mendefinisikan fungsi dua argumen baru sebagai bagian dari perpustakaan aplikasi saya?
David Spector
4

menggunakan 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)

Contoh

// /////////////    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

Emmanuel NK
sumber
Jawaban Terbaik. Tetapi apakah ada alasan untuk menggunakan ${f}alih-alih f untuk nilai akumulasi?
David Spector
1
Jika Anda ingin SEMUA string yang diberikan diganti, bukan hanya yang pertama, tambahkan flag g: "const result1 = arrayOfObjects.reduce ((f, s) => ${f}.replace (new RegExp (Object.keys (s) [ 0], 'g'), s [Object.keys (s) [0]]), kalimat1) "
David Spector
2

Kalau-kalau ada orang yang bertanya-tanya mengapa solusi poster asli tidak berfungsi:

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."
mendongkrak
sumber
ha ha ... dianalisis dengan baik ... thumbsup
Deepa MG
1

fungsi biasa pengguna untuk menentukan pola untuk mengganti dan kemudian menggunakan fungsi ganti untuk bekerja pada string input,

var i = new RegExp('"{','g'),
    j = new RegExp('}"','g'),
    k = data.replace(i,'{').replace(j,'}');
KARTHIKEYAN.A
sumber
Jika Anda tidak sadar lewati, tetapi jangan katakan itu adalah jawaban yang salah. Kasing saya "{" a ": 1," b ": 2}" seperti itulah yang saya gunakan untuk mengganti cara di atas. Jika itu membantu orang lain jika mereka menginginkan orang lain, jawabannya bukan hanya untuk Anda. @Carr
KARTHIKEYAN.A
Sekali lagi, Anda hanya memberikan jawaban yang tidak berarti, apa yang Anda lakukan adalah penanya sudah dapat melakukan dalam pertanyaan, jawaban ini akan menyesatkan orang bahwa mereka mungkin berpikir baru dan memanfaatkan RegExpobjek tersebut dapat memecahkan masalah
Carr
Dalam hal ini, Anda masih memiliki masalah yang sama dengan pertanyaan penanya ketika Anda melakukannyavar i = new RegExp('}','g'), j = new RegExp('{','g'), k = data.replace(i,'{').replace(j,'}');
Carr
1

Dengan paket ganti saya , Anda dapat melakukan hal berikut:

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.'
Kodie Grantham
sumber
Paket ini luar biasa :) Bekerja persis seperti yang saya harapkan
Wisnu 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."
Anand Kumar Singh
sumber
3
OP bertanya "Apakah mungkin untuk mengganti beberapa string dengan beberapa string lainnya pada saat yang sama ". Ini adalah tiga langkah terpisah.
LittleBobbyTables - Au Revoir
1

Anda dapat menemukan dan mengganti string menggunakan pembatas.

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;
}

Naresh Kumar
sumber
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;
}

/ * replaceSome metode untuk string yang dibutuhkan, sebanyak argumen yang kita inginkan dan menggantikan semuanya dengan argumen terakhir yang kita tentukan 2013 CopyRights disimpan untuk: Max Ahmed ini adalah contoh:

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/

nazih ahmed
sumber
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>
Jalaluddin Rumi
sumber
0

Saya menulis paket npm ini stringinject https://www.npmjs.com/package/stringinject yang memungkinkan Anda melakukan hal berikut

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

yang akan mengganti {0} dan {1} dengan item-item array dan mengembalikan string berikut

"this is a test string for stringInject"

atau Anda bisa mengganti placeholder dengan kunci objek dan nilai seperti:

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

"My username is tjcafferkey on Github" 
tjcafferkey
sumber
0

Anda dapat menggunakan https://www.npmjs.com/package/union-replacer untuk tujuan ini. Ini pada dasarnya adalah string.replace(regexp, ...)rekanan, yang memungkinkan beberapa penggantian terjadi dalam satu pass sekaligus mempertahankan kekuatan penuh string.replace(...).

Pengungkapan: Saya adalah penulis. Perpustakaan dikembangkan untuk mendukung penggantian yang dapat dikonfigurasi pengguna yang lebih kompleks dan menangani semua hal yang bermasalah seperti kelompok tangkap, referensi-kembali dan penggantian fungsi panggilan balik.

Solusi di atas cukup baik untuk penggantian string yang tepat.

Martin Čížek
sumber
-1

Saya sedikit memperluas @BenMcCormicks. Dia bekerja untuk string reguler tetapi tidak jika saya melarikan diri karakter atau wildcard. Inilah yang saya lakukan

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)

mengembalikan "bla bla 234433 bla bla"

Dengan cara ini akan cocok dengan kunci di mapObj dan bukan kata yang cocok '

Drew Landgrave
sumber
// tidak berharga: replaceAll ("Saya punya kucing, anjing, dan kambing.", {cat: "dog", dog: "kambing", kambing: "kucing"}) // menghasilkan: "Saya punya kucing , kucing, dan kucing. "
devon
-3

Solusi dengan Jquery (pertama-tama sertakan file ini): Ganti banyak string dengan banyak string lainnya:

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));
    });
});
Super Model
sumber
Apakah solusi ini membutuhkan JQuery?
Anderson Green
Tag javascript ditambahkan dalam pertanyaan, dan jquery adalah lavariary dari javascript.
Super Model
2
@Super javascript tag added in question, and jquery is a libarary of javascript.Hmmm bahwa logika tidak aktif, harus sebaliknya, dan juga hanya kepala - dari info tag javascript: " Kecuali tag lain untuk kerangka / pustaka juga disertakan, jawaban JavaScript murni diharapkan. "
Traxo
@Anderson Green, ya jquery diperlukan untuk skrip di atas.
Super Model
@ Traxo, di sebagian besar aplikasi web kami menggunakan kerangka kerja (bootstrap / materi google). Jquery termasuk dalam semua kerangka kerja modern. Jadi, jquery adalah item yang diperlukan untuk aplikasi web.
Super Model