Search and replace for a specific pattern - javascript

I have the following requirement:
I have a url as
var url = '/test/mybin/processes/{testName}/test?id={testId}';
The url can contain any number of {} in it. Lets say above it has {} at 2 places {testName} and {testId}. It can have any number of such params.
I need to replace the value of each such params with the real value.
I need to first know the name of attribute inside each {} and replace them with actual values before loading the url.
Lets say in above example, I have to first extract the names of each attribute inside {} and replace them with actual values.
In my method:
testName="Test" and testId=1
so, I want the url value to be
'/test/mybin/processes/Test/test?id=1'.
Could you please let me the best way to achieve this?
Thanks, Tani

Something like this should do the trick:
var obj = { testName : "mytest", testId:1 };
var url = '/test/mybin/processes/{testName}/test?id={testId}';
var regex = /{(.*?)}/g;
var replaced = url.replace(regex, function(m,p1) {
return obj[p1];
});
alert(replaced);
The regex /{(.*?)}/ will match any thing between curly braces (non-greedy) and puts the contents in a group that can be replaced.
Your regex from your comments could easily be fixed with the additon of the /g flag:
/\{[^\}]*\}/g
But you may find it easier to add brackets for grouping to make it easier to extract the actual contents between the braces without the braces themselves:
/\{([^\}]*)\}/g
Also note that in this context the { and } in your regex don't need escaping, but it doesn't hurt to include the escapes \

a regex combined with String.protoype.replace() is a nice way to go:
function f(map,url) {
var pattern = /{(\w+)}/g;
var replacer = function(a,b){
return map[b];
};
var o = url.replace(pattern,replacer);
return o;
}
http://jsfiddle.net/sean9999/poctcdLp

Related

How could one split a comma delimited string while ignoring the commas which are in braces?

I have a string which represents the attributes of a function:
str = "'MyCommunities', null, {'viewAllLink':'https://cpkornferrybruceapidev.azurewebsites.net', 'clientId':'078c49af-bb40-44c3-a685-539a84cc5de7', 'subscriptionId':'64fc6f58-2a67-472b-b57f-f0f5441e7992'}"
There are 3 attributes: My Communities, null, {...}
I would like to split the string into array containing these 3 values but without splitting the object literal.
I believe I need to construct a regular expression which would allow me to str.split(//) however I am not able to get the 3 attributes which I need.
Any help would be appreciated.
If be sure the string doesn't have extra ' in the value of each element, I think one quick way is treat it as one JSON string, then pull out the element you need.
The codes are like below:
let str = "'MyCommunities', null, {'viewAllLink':'https://cpkornferrybruceapidev.azurewebsites.net', 'clientId':'078c49af-bb40-44c3-a685-539a84cc5de7', 'subscriptionId':'64fc6f58-2a67-472b-b57f-f0f5441e7992'}"
console.log(JSON.parse('[' + str.replace(/'/g, '"') +']'))
If you don't have nested braces and if comma is always before {, then you can do this:
var re = /(\{[^}]+\})/;
var result = [];
str.split(re).forEach(function(part) {
if (part.match(re) {
result.push(part);
} else {
var parts = part.split(',').map((x) => x.trim()).filter(Boolean);
result = result.concat(parts);
}
});
if you have something before braces or if braces are nested you will need more compicated parser.
My first suggestion would be to find a different way to get the string formatted coming into your system. If that is not feasible, you can do the following regex (note: it is super fragile):
/\,(?![^{]*})/
and get the groupings like so:
list = str.split(/\,(?![^{]*})/)
I would use the second limit parameter of split() (docs) to stop cutting before the object literal:
var str = "'MyCommunities', null, {'viewAllLink':'https://cpkornferrybruceapidev.azurewebsites.net', 'clientId':'078c49af-bb40-44c3-a685-539a84cc5de7', 'subscriptionId':'64fc6f58-2a67-472b-b57f-f0f5441e7992'}";
console.log(str.split(', ', 3));

Regex - Match a string between second occurance of characters

I have a string of text that looks something like this:
?q=search&something=that&this=example/
In that example, I need to grab that . I'm using the following regex below:
var re = new RegExp("\&(.*?)\&");
Which going re[1] is giving me:
something=that - but it needs to be only that
I tried:
var re = new RegExp("\=(.*?)\&");
But that gives me everything from the first equals sign, so:
search&something=that
Is the output when it just needs to be:
that
I need to somehow target the second occurrences of 2 characters and grab whats in between them. How best do I go about this?
You can use
/something=([^&]+)/
and take the first group, see the JavaScript example:
let url = '?q=search&something=that&this=example/';
let regex = /something=([^&]+)/
let match = regex.exec(url);
console.log(match[1]);
split seems more suited to your case:
"?q=search&something=that&this=example/".split("&")[1].split("=")[1]
Then you could also implement a simple method to extract any wanted value :
function getValue(query, index) {
const obj = query.split("&")[index];
if(obj) obj.split("=")[1]
}
getValue("?q=search&something=that&this=example/", 1);

javascript, regex parse string content in curly brackets

i am new to regex. I am trying to parse all contents inside curly brackets in a string. I looked up this post as a reference and did exactly as one of the answers suggest, however the result is unexpected.
Here is what i did
var abc = "test/abcd{string1}test{string2}test" //any string
var regex = /{(.+?)}/
regex.exec(abc) // i got ["{string1}", "string1"]
//where i am expecting ["string1", "string2"]
i think i am missing something, what am i doing wrong?
update
i was able to get it with /g for a global search
var regex = /{(.*?)}/g
abc.match(regex) //gives ["{string1}", "{string2}"]
how can i get the string w/o brackets?
"test/abcd{string1}test{string2}test".match(/[^{}]+(?=\})/g)
produces
["string1", "string2"]
It assumes that every } has a corresponding { before it and {...} sections do not nest. It will also not capture the content of empty {} sections.
var abc = "test/abcd{string1}test{string2}test" //any string
var regex = /{(.+?)}/g
var matches;
while(matches = regex.exec(abc))
console.log(matches);
Try this:
var abc = "test/abcd{string1}test{string2}test" //any string
var regex = /{(.+?)}/g //g flag so the regex is global
abc.match(regex) //find every match
a good place to read about Regex in javascript is here, and a nice place to test is here
good luck!
Nothing wrong. But you'll need to look at your capturing groups (the second element in the array) to get the content you wanted (you can ignore the first). To get all occurences, it's not enough to run exec once, you'll need to loop over the results using match.
Edit: nevermind that, afaik you can't access capturing groups with match. A simpler solution would be using a positive lookahead, as Mike Samuel suggested.
This result:
["{string1}", "string1"]
is showing you that for the first match, the entire regex matched "{string1}" and the first capturing parentheses matched "string1".
If you want to get all matches and see all capturing parens of each match, you can use the "g" flag and loop through, calling exec() multiple times like this:
var abc = "test/abcd{string1}test{string2}test"; //any string
var regex = /{(.+?)}/g;
var match, results = [];
while (match = regex.exec(abc)) {
results.push(match[1]); // save first captured parens sub-match into results array
}
// results == ["string1", "string2"]
You can see it work here: http://jsfiddle.net/jfriend00/sapfm/
try this for file
const fs = require('fs');
fs.readFile('logs.txt', function(err, data) {
if(err) throw err;
const paragraph = "'" + data + "'";
const regex = /\d+\<;>\S+\<;>(\d+)\<;/g;
const found = paragraph.match(regex);
console.log(found);
})

Can regex matches in javascript match any word after an equal operator?

I am trying to target ?state=wildcard in this statement :
?state=uncompleted&dancing=yes
I would like to target the entire line ?state=uncomplete, but also allow it to find whatever word would be after the = operator. So uncomplete could also be completed, unscheduled, or what have you.
A caveat I am having is granted I could target the wildcard before the ampersand, but what if there is no ampersand and the param state is by itself?
Try this regular expression:
var regex = /\?state=([^&]+)/;
var match = '?state=uncompleted&dancing=yes'.match(regex);
match; // => ["?state=uncompleted", "uncompleted"]
It will match every character after the string "\?state=" except an ampersand, all the way to the end of the string, if necessary.
Alternative regex: /\?state=(.+?)(?:&|$)/
It will match everything up to the first & char or the end of the string
IMHO, you don't need regex here. As we all know, regexes tend to be slow, especially when using look aheads. Why not do something like this:
var URI = '?state=done&user=ME'.split('&');
var passedVals = [];
This gives us ['?state=done','user=ME'], now just do a for loop:
for (var i=0;i<URI.length;i++)
{
passedVals.push(URI[i].split('=')[1]);
}
Passed Vals wil contain whatever you need. The added benefit of this is that you can parse a request into an Object:
var URI = 'state=done&user=ME'.split('&');
var urlObjects ={};
for (var i=0;i<URI.length;i++)
{
urlObjects[URI[i].split('=')[0]] = URI[i].split('=')[1];
}
I left out the '?' at the start of the string, because a simple .replace('?','') can fix that easily...
You can match as many characters that are not a &. If there aren't any &s at all, that will of course also work:
/(\?state=[^&]+)/.exec("?state=uncompleted");
/(\?state=[^&]+)/.exec("?state=uncompleted&a=1");
// both: ["?state=uncompleted", "?state=uncompleted"]

Passing regex modifier options to RegExp object

I am trying to create something similar to this:
var regexp_loc = /e/i;
except I want the regexp to be dependent on a string, so I tried to use new RegExp but I couldn't get what i wanted.
Basically I want the e in the above regexp to be a string variable but I fail with the syntax.
I tried something like this:
var keyword = "something";
var test_regexp = new RegExp("/" + keyword + "/i");
Basically I want to search for a sub string in a larger string then replace the string with some other string, case insensitive.
regards,
alexander
You need to pass the second parameter:
var r = new RegExp(keyword, "i");
You will also need to escape any special characters in the string to prevent regex injection attacks.
You should also remember to watch out for escape characters within a string...
For example if you wished to detect for a single number \d{1} and you did this...
var pattern = "\d{1}";
var re = new RegExp(pattern);
re.exec("1"); // fail! :(
that would fail as the initial \ is an escape character, you would need to "escape the escape", like so...
var pattern = "\\d{1}" // <-- spot the extra '\'
var re = new RegExp(pattern);
re.exec("1"); // success! :D
When using the RegExp constructor, you don't need the slashes like you do when using a regexp literal. So:
new RegExp(keyword, "i");
Note that you pass in the flags in the second parameter. See here for more info.
Want to share an example here:
I want to replace a string like: hi[var1][var2] to hi[newVar][var2].
and var1 are dynamic generated in the page.
so I had to use:
var regex = new RegExp("\\\\["+var1+"\\\\]",'ig');
mystring.replace(regex,'[newVar]');
This works pretty good to me. in case anyone need this like me.
The reason I have to go with [] is var1 might be a very easy pattern itself, adding the [] would be much accurate.
var keyword = "something";
var test_regexp = new RegExp(something,"i");
You need to convert RegExp, you actually can create a simple function to do it for you:
function toReg(str) {
if(!str || typeof str !== "string") {
return;
}
return new RegExp(str, "i");
}
and call it like:
toReg("something")

Categories