3

I have this kind of sentences:

var str = 'The <adjective> <noun> and <noun> <title>';

I would like to replace each <pattern> by a random value from their related array.

In my previous example I'd like to get something similar to:

var adjectives = ['big' 'small' 'funny'];
var nouns = ['dog', 'horse', 'ship'];
var title = ['bar', 'pub', 'club'];

var str = 'The <adjective> <noun> and <noun> <title>';
var r = str.replacePatterns({ noun: nouns, adjective: adjectives, title: titles });
console.log(r); // The big horse and ship club

I almost get it by didn't tough about same pattern (e. g. <noun>) twice in the same sentence. So I generate only one random value for each pattern...

String.prototype.replacePatterns = function (hash) {

    var string = this,
        key;

    for (key in hash) {
        if (hash.hasOwnProperty(key)) {
            var randomValue = hash[key][Math.floor(Math.random() * hash[key].length)];
            string = string.replace(new RegExp('\\<' + key + '\\>', 'gm'), randomValue);
        }
    }

    return string;
};

Could you help me to get something replacing each pattern by a random value instead of a global replacement?

I don't know how to loop result of a regex to replace the matches in the original sentence (with random value each time).

2
  • 1
    Use a callback function for the substitution, and let that return the random values. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Jun 23, 2016 at 12:10
  • @CBroe Indeed... I replaced randomValueby a function returning the random value and it works! Commented Jun 23, 2016 at 12:12

2 Answers 2

3

replace accepts a function as its second argument, which is called for each replacement and can return the value to replace with. So use a function and move the random number generation into it:

String.prototype.replacePatterns = function (hash) {

    var string = this,
        key,
        entry;

    for (key in hash) {
        if (hash.hasOwnProperty(key)) {
            entry = hash[key]
            string = string.replace(new RegExp('\\<' + key + '\\>', 'gm'), function() {
                return entry[Math.floor(Math.random() * entry.length)]
            });
        }
    }

    return string;
};

You don't need it here, but just FYI, the function receives the matched text as its first argument, and if you have capture groups in your regular expression (you don't), it receives them as subsequent arguments. Details in the MDN page for String#replace or, of course, the spec.

Sign up to request clarification or add additional context in comments.

Comments

2

You can also use a regex instead of looping. Something like

function replacePatterns(str, options) {
  options = options || {
    adjective: ['big', 'small', 'funny'],
    noun: ['dog', 'horse', 'ship'],
    title: ['bar', 'pub', 'club']
  }

  return str.replace(/<(.*?)>/g, function(match) {
    match = match.replace(/<|>/g,'')
    return options[match][Math.floor(Math.random()*options[match].length)]
  })
}

Also added in the optional options hash for added flexibility.

Comments

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.