user3253797
user3253797

Reputation: 183

Javascript Pattern Replace

I have an object like this

myObj = {
    "strPattern": "Name: #name#<br>Surname: #sname#<br>Location: #loc#",
    "name": "John",
    "sname": "Doe",
    "loc": "LA"
}

Now I need a function which will take my object and return it as a string with the help of its pattern.

Expected Result : "Name: John<br>Surname: Doe<br>Location: LA"

I couldn't do it with JavaScript's replace method and I dont know how to do it. Thank for your help.

By the way, number of subStrs can be dynamic. For example there are 3 subStrings in this example but it can be 5 or 10 for other objects. #age#, #gender#, etc...

Upvotes: 0

Views: 165

Answers (5)

user1636522
user1636522

Reputation:

The following function can be used to improve performances. However, it's useless if you don't need to use the template multiple times.

function compile(tpl) {
    tpl = tpl.split(/#(.*?)#/);
    return Function('return [' + tpl.map(function (v, i) {
        if (i % 2) return 'this["' + v + '"]';
        return v && '"' + v.replace(/"/g, '\\"') + '"';
    }).join(',') + '].join("");');
}

Usage example :

var myObj = {
    "strPattern": "Name: #name#<br>Surname: #sname#<br>Location: #loc#",
    "name": "John",
    "sname": "Doe",
    "loc": "LA"
};

myObj.strPattern = compile(myObj.strPattern).call(myObj);

More interesting :

var tpl = '#first# #last#',
    compiled = compile(tpl);

compiled.call({ first: 'John', last: 'Doe' }); // "John Doe"
compiled.call({ first: 'Walter', last: 'White' }); // "Walter White"

More details here : https://stackoverflow.com/a/20886377/1636522.

Upvotes: 2

arslion
arslion

Reputation: 440

function getFilled(myObj){
  pattern = myObj.strPattern.match(/#(.*?)#/g);
  for (key in pattern){
    myObj.strPattern =  myObj.strPattern.replace(pattern[key],myObj[pattern[key].substr(1,pattern[key].length-2)])
  }
return myObj.strPattern;
}

console.log(getFilled(myObj)); 

Upvotes: 0

user2377528
user2377528

Reputation:

myObj = {
    "strPattern": "Name: #subStr1#<br>Surname: #subStr2#<br>Location: #subStr3#",
    "subStr1": "John",
    "subStr2": "Doe",
    "subStr3": "LA"
}
function patternMatcher(myObj){
  strp = myObj.strPattern;
  pattern = strp.match(/#(.*?)#/g);

  for (key in pattern){
    origKey = pattern[key].substr(1,pattern[key].length-2);
    strp =  strp.replace(pattern[key],myObj[origKey])
  }
return strp;
}

console.log(patternMatcher(myObj)); 

Here's Your Code running example link

Upvotes: 0

Pebbl
Pebbl

Reputation: 36035

Another way to approach this, that works through only the replacements that appear in the string, would be:

var Stringify = function(obj){
  return obj.strPattern.replace(/#([a-z]+)#/gi, function(match,group){
    return obj[group] || match;
  });
};

var str = Stringify({
  "strPattern": "Name: #name#<br>Surname: #sname#<br>Location: #loc#",
  "name": "John",
  "sname": "Doe",
  "loc": "LA"
});

This also could be of interest to those wanting to use string.replace(pattern, function).

When did all browsers start supporting the String.replace(regexp, replacement_function)?

Upvotes: 0

Tasos K.
Tasos K.

Reputation: 8087

You can loop to an objects properties using the for (var key in myObj) structure. In every loop the key variable holds the name of each property and you can access its value with the myObj[key] variable.

An example of how you could use in your scenario could be like this.

var myObj = {
    "strPattern": "Name: #subStr1#<br>Surname: #subStr2#<br>Location: #subStr3#",
    "subStr1": "John",
    "subStr2": "Doe",
    "subStr3": "LA"
};

var html = myObj["strPattern"];

for (var key in myObj) {
   var obj = myObj[key];
    if(key !== "strPattern") {
        html = html.replace("#" + key + "#",obj);
    }
}

jQuery('#result').html(html);

I also made a jsfiddle with it.

Edit: As @Andreas mentioned in a comment, the order of accessing the properties is not guaranteed, I adjusted my code snippet accordingly.

Upvotes: 2

Related Questions