简体   繁体   中英

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

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"

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM