gdex
gdex

Reputation: 465

JavaScript Regex capture and replace

I have a string that looks like this:

var whereClause = "p_id eq @p_id@ and idr_user_id eq @idr_user_id@";

I have the following regular expression to capture the tokens /(@\w+@)/g

I would like to be able to replace each occurrence with a different value something like

whereClause.replace(/(@\w@)/g, projectID, userID);

Will this work? Any Ideas would be helpful...

Upvotes: 4

Views: 1077

Answers (3)

talemyn
talemyn

Reputation: 7950

I've done something somewhat similar to this before for dynamic error messaging. To do it with what you are doing, it would go something like this.

function populateMessage(messageTemplate, replacementVals) {
    var newMessage = messageTemplate;

    for (var targetVal in replacementVals) {
        if (replacementVals.hasOwnProperty(targetVal)) {
            newMessage = newMessage .replace("@" + targetVal + "@", replacementVals[targetVal]);
        }
    }

    return newMessage;
}

var whereClause = "p_id eq @p_id@ and idr_user_id eq @idr_user_id@";
var replacementText = {"p_id": "SOME_TEXT_1", "idr_user_id": "SOME_TEXT_2"};
var outputValue = populateMessage(whereClause, replacementText);

The one of the pluses of this approach is that you can use different whereClause and replacementText variables for different situations and the replacement will only happen if the .replace finds a match for the defined keys. So:

var whereClause1 = "p_id eq @p_id@ and idr_user_id eq @idr_user_id@";
var whereClause2 = "p_id eq @p_id@";
var whereClause3 = "idr_user_id eq @idr_user_id@";

. . . could all be "served" by:

var replacementText = {"p_id": "SOME_TEXT_1", "idr_user_id": "SOME_TEXT_2"};

. . . and result in valid messages.

It would also be REALLY easy to populate the replacementText object with dynamic values, if that was needed.

Upvotes: 0

elclanrs
elclanrs

Reputation: 94101

You could aim for something like this:

template(string, {key: value, key: value});

It could be implemented in a few lines using the replace callback:

function template(text, obj) {
  var regex = /@(\w+)@/g;
  return text.replace(regex, function(_, match) {
    return obj[match] || _;
  });
}

// Usage:
var str = 'p_id eq @p_id@ and idr_user_id eq @idr_user_id@';
var result = template(str, {p_id: 123, idr_user_id: 'ABC'});
//^ "p_d eq 123 and idr_user_id eq ABC"

If you need different regex or structure, you can create a simple closure around those, like:

function template(regex, fn) {
  return function (text, obj) {
    return text.replace(regex, function(_, match) {
      return fn.call(obj, match);
    });
  }
};

// Using an array
var myTemplate = template(/%(\d+)/g, function(x) {
  return this[--x];
});
var str = 'Hello %1, foo %2';
var result = myTemplate(str, ['world', 'baz']);
//^ "Hello world, foo baz"

Upvotes: 7

rid
rid

Reputation: 63462

You could do something like:

whereClause.replace(/@\w+@/g, function(token) {
    switch (token) {
        case '@p_id@': return projectID;
        case '@idr_user_id@': return userID;
    }
    return token;
});

Upvotes: 4

Related Questions