0

I have an XML file with texts in a certain language and I need to traverse it and translate certain expressions. I was thinkging about creating an array containing the expressions and an array containing the replacements:

var searchFor = ['Foo', 'Bar'];
var replaceWith = ['Bar', 'Foo'];

Is there some way I can traverse the XML effectively replacing all items in the first array with the next?

xml.each(function(){
  $(this).text($(this).text().multiReplace(searchFor, replaceWith));
});

What I'm looking for is a javascript function that is equivalent to the PHP function str_replace that can take in an array for the first and second parameters: http://php.net/manual/en/function.str-replace.php

'FooBar'.multiReplace(searchFor,replaceWith); // should return 'BarFoo'

PS: Alternative solutions are also welcome.

3 Answers 3

1

For a very simple implementation, since you have jQuery you can use $.each inside you callback :

var txt = $(this).text();
$.each(searchFor, function(i,v){ 
    txt.replace(v, replaceWith[i]); 
});
$(this).text(txt);

If you want to swap values, you have to insert tokens that you are sure do not exist in your string. For instance, '##i##'. (Search for the regexp '##\d+##' in your string. If it exists, then add enclosing '#' and search again until you find a token that you know do not exist in the string.)

var txt = $(this).text();
var tokens = [];
$.each(searchFor, function(i,v){ 
    var token = "##" + i + "##";
    tokens.push(token);
    txt.replace(v, token); 
});
$.each(tokens, function(i,v){ 
    txt.replace(v, searchFor[i]); 
});
$(this).text(txt);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I like the solution, but I was hoping to acheive this without travering the text more than once.
1

I have found a solution that seems to work fine. I have extended the String object with the multiReplace function that takes a map of translations as a parameter and returns a new string with the replaced expressions.

String.prototype.multiReplace = function(translations){
  var regexStr = '';
    var result = '';
    for(var key in translations){
        regexStr += key + '|';
    }
    regexStr = '(' + regexStr.substring(0,regexStr.length-1) + ')';
    var rx = new RegExp(regexStr,'g');
    result = this.replace(rx, function(match){
        return translations[match.toLowerCase()];
    });
    return result;
}
    var translations = {
      'Foo':'Bar',
      'Bar':'Foo'
    };
    text = 'FooBarFooFooBarBarFooBarFooFoo';
    text = text.multiReplace(translations);
    // text = "BarFooBarBarFooFooBarFooBarBar"

2 Comments

This could break quite easily if you have regex special characters (like [ or () in your keys.
Thanks, didn't think about that :) An improvement would be to escape the keys in the multiReplace function, but I think I'll leave it as it is for now, as this is not going into production and I control the translations myself :)
0

I have this function like ~5 years already. I don't know where i got this.

function str_replace (search, replace, subject) {
    var result = "";
    var  oldi = 0;
    for (i = subject.indexOf (search); i > -1; i = subject.indexOf (search, i)) {
        result += subject.substring (oldi, i);
        result += replace;
        i += search.length;
        oldi = i;
    }
    return result + subject.substring (oldi, subject.length);
}

4 Comments

Isn't this the same as the /g modifier, i.e. 'FooBar'.replace(/Foo/g, 'Bar'); ?
Dunno. But it does same what str_replace does.
Not if you send in arrays in the search and replace parameters :)
So only modification needed to make is chek is there arrays, if so, then replace acordinly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.