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...
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...
Share Improve this question asked Jan 17, 2014 at 22:06 gdexgdex 4651 gold badge4 silver badges10 bronze badges 3- You're exposing a where clause to be manipulated by the client? Sounds like a security issue waiting to happen. – adam0101 Commented Jan 17, 2014 at 22:09
- @adam0101, The where clause is filled in by by values queried from a sqlLite database not human input. – gdex Commented Jan 17, 2014 at 22:12
- 1 This will not work. The JS replace method only takes 2 parameters. Any additional parameters would be ignored. You'd have to create a RegExp object, run the regular expression against the string, and loop through the matches. – Bic Commented Jan 17, 2014 at 22:12
3 Answers
Reset to default 7You 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.