Javascript find and replace string with variable values - javascript

I have an angular app, but I have one page that needs to be pre-rendered with no javascript (for printing and PDF), some of the content is loaded with the Angular variable inputs {{field(10)}}
I pre-load the content but need a way to find and replace the string so that:
{{field(10)}}
is changed into the value of this
submission.inputs[10]
So for example:
var string = 'This is some content: {{field[10]}}';
var submission.inputs[10] = 'replace value';
I want the new string to be this
var newString = 'This is some content: replace value';
This is running in Node so it has the latest version of Javascript.
I tried this:
var newString = string.replace(/\{{(.+?)}}/g, submission.inputs[$1]);
But I don't think my syntax is correct.

Your current regex extracts all the text contained within {{}} with its capture group. But you only want the index of the replacement, which is contained within the [], and not the entire string itself. So you have two options:
Modify regex to capture only the index, so that would look like /{{field\[(.+?)\]}}/, where the capture group now only takes the number within the brackets.
Leave the original regex alone, but change the replace function to extract the number from the returned match. In this case you'll have a second regex (or some other method) to extract the number from the matched string (in this case, get "10" out of "field[10]").
Here's an example demonstrating both:
var string = 'This is some content: {{field[10]}}';
var submission = {inputs: []};
submission.inputs[10] = 'replace value';
// I want the new string to be this
// var newString = 'This is some content: replace value';
var newString = string.replace(/{{field\[(.+?)\]}}/g, (match, cap1) => submission.inputs[cap1]);
console.log(newString)
// OR:
var otherNewString = string.replace(/\{{(.+?)}}/g, (match, cap1) => submission.inputs[cap1.match(/\[(.+?)\]/)[1]]);
console.log(otherNewString)

You can use the following regex to extract the contents between {{field[ and ]}} as the snippet below shows. The snippet uses a callback in the replace function and passes the captured group's value to it so that an appropriate value may be returned (submission.inputs[b] where b is the number you want: 10 in this case).
{{[^[]+\[([^\]]+)]}}
{{ Match this literally
[^[]+ Match any character except [ one or more times
\[ Match [ literally
([^\]]+) Capture any character except ] one or more times into capture group 1. This is the value you want
]}} Match this literally
var string = 'This is some content: {{field[10]}}'
var submission = {inputs:[]}
submission.inputs[10] = 'replace value'
var newString = string.replace(/{{[^[]+\[([^\]]+)]}}/g, function(a, b) { return submission.inputs[b] })
console.log(newString)

Related

Extract part of a string which start with a certain word in Javascript

I have the following string
"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,
I need to get string after "ssu":" the Result should be 89c4eef0-3a0d-47ae-a97f-42adafa7cf8f. How do I do it in Javascript but very simple? I am thinking to collect 36 character after "ssu":".
You could build a valid JSON string and parse it and get the wanted property ssu.
var string = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,',
object = JSON.parse(`{${string.slice(0, -1)}}`), // slice for removing the last comma
ssu = object.ssu;
console.log(ssu);
One solution would be to use the following regular expression:
/\"ssu\":\"([\w-]+)\"/
This pattern basically means:
\"ssu\":\" , start searching from the first instance of "ssu":"
([\w-]+) , collect a "group" of one or more alphanumeric characters \w and hypens -
\", look for a " at the end of the group
Using a group allows you to extract a portion of the matched pattern via the String#match method that is of interest to you which in your case is the guid that corresponds to ([\w-]+)
A working example of this would be:
const str = `"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,`
const value = str.match(/\"ssu\":\"([\w-]+)\"/)[1]
console.log(value);
Update: Extract multiple groupings that occour in string
To extract values for multiple occurances of the "ssu" key in your input string, you could use the String#matchAll() method to achieve that as shown:
const str = `"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,"ssu":"value-of-second-ssu","ssu":"value-of-third-ssu"`;
const values =
/* Obtain array of matches for pattern */
[...str.matchAll(/\"ssu\":\"([\w-]+)\"/g)]
/* Extract only the value from pattern group */
.map(([,value]) => value);
console.log(values);
Note that for this to work as expected, the /g flag must be added to the end of the original pattern. Hope that helps!
Use this regExp: /(?!"ssu":")(\w+-)+\w+/
const str = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,';
const re = /(?!"ssu":")(\w+-)+\w+/;
const res = str.match(re)[0];
console.log(res);
You can use regular expressions.
var str = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,'
var minhaRE = new RegExp("[a-z|0-9]*-[a-z|0-9|-]*");
minhaRE.exec(str)
OutPut: Array [ "89c4eef0-3a0d-47ae-a97f-42adafa7cf8f" ]
Looks almost like a JSON string.
So with a small change it can be parsed to an object.
var str = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049, ';
var obj = JSON.parse('{'+str.replace(/[, ]+$/,'')+'}');
console.log(obj.ssu)

How to extract two strings from url using regex?

I've matched a string successfully, but I need to split it and add some new segments to URL. If it is possible by regex, How to match url and extract two strings like in the example below?
Current result:
["domain.com/collection/430000000000000"]
Desired result:
["domain.com/collection/", "430000000000000"]
Current code:
var reg = new RegExp('domain.com\/collection\/[0-9]+');
var str = 'http://localhost:3000/#/domain.com/collection/430000000000000?page=0&layout=grid';
console.log(str.match(reg));
You want Regex Capture Groups.
Put the parts you want to extract into braces like this, each part forming a matching group:
new RegExp('(domain.com\/collection\/)([0-9]+)')
Then after matching, you can extract each group content by index, with index 0 being the whole string match, 1 the first group, 2 the second etc. (thanks for the addendum, jcubic!).
This is done with exec() on the regex string like described here:
/\d(\d)\d/.exec("123");
// → ["123", "2"]
First comes the whole match, then the group matches in the sequence they appear in the pattern.
You can declare an array and then fill it with the required values that you can capture with parentheses (thus, making use of capturing groups):
var reg = /(domain.com\/collection)\/([0-9]+)/g;
// ^ ^ ^ ^
var str = 'http://localhost:3000/#/domain.com/collection/430000000000000?page=0&layout=grid';
var arr = [];
while ((m = reg.exec(str)) !== null) {
arr.push(m[1]);
arr.push(m[2]);
}
console.log(arr);
Output: ["domain.com/collection", "430000000000000"]

Why is this regex matching also words within a non-capturing group?

I have this string (notice the multi-line syntax):
var str = ` Number One: Get this
Number Two: And this`;
And I want a regex that returns (with match):
[str, 'Get this', 'And this']
So I tried str.match(/Number (?:One|Two): (.*)/g);, but that's returning:
["Number One: Get this", "Number Two: And this"]
There can be any whitespace/line-breaks before any "Number" word.
Why doesn't it return only what is inside of the capturing group? Am I misundersating something? And how can I achieve the desired result?
Per the MDN documentation for String.match:
If the regular expression includes the g flag, the method returns an Array containing all matched substrings rather than match objects. Captured groups are not returned. If there were no matches, the method returns null.
(emphasis mine).
So, what you want is not possible.
The same page adds:
if you want to obtain capture groups and the global flag is set, you need to use RegExp.exec() instead.
so if you're willing to give on using match, you can write your own function that repeatedly applies the regex, gets the captured substrings, and builds an array.
Or, for your specific case, you could write something like this:
var these = str.split(/(?:^|\n)\s*Number (?:One|Two): /);
these[0] = str;
Replace and store the result in a new string, like this:
var str = ` Number One: Get this
Number Two: And this`;
var output = str.replace(/Number (?:One|Two): (.*)/g, "$1");
console.log(output);
which outputs:
Get this
And this
If you want the match array like you requested, you can try this:
var getMatch = function(string, split, regex) {
var match = string.replace(regex, "$1" + split);
match = match.split(split);
match = match.reverse();
match.push(string);
match = match.reverse();
match.pop();
return match;
}
var str = ` Number One: Get this
Number Two: And this`;
var regex = /Number (?:One|Two): (.*)/g;
var match = getMatch(str, "#!SPLIT!#", regex);
console.log(match);
which displays the array as desired:
[ ' Number One: Get this\n Number Two: And this',
' Get this',
'\n And this' ]
Where split (here #!SPLIT!#) should be a unique string to split the matches. Note that this only works for single groups. For multi groups add a variable indicating the number of groups and add a for loop constructing "$1 $2 $3 $4 ..." + split.
Try
var str = " Number One: Get this\
Number Two: And this";
// `/\w+\s+\w+(?=\s|$)/g` match one or more alphanumeric characters ,
// followed by one or more space characters ,
// followed by one or more alphanumeric characters ,
// if following space or end of input , set `g` flag
// return `res` array `["Get this", "And this"]`
var res = str.match(/\w+\s+\w+(?=\s|$)/g);
document.write(JSON.stringify(res));

Search and replace and remember with which word the string has been replaced in regex

How do i find which substrings were replaced when regex replace was applied in javascript
Main string : abcSSSdeSSfghEEEijSSSkEEElmSSSnSSSEEEopEEE
I want to replace all the minimal length substrings starting with 'SSS' and ends with 'EEE'. with .*
Upon applying a desired function i should get modified string
abc.*ij.*lmSSSn.*opEEE
and also the array for replaced strings as follows :
[ SSSdeSSfghEEE, SSSkEEE, SSSEEE ]
How to efficiently implement the above desired function
Pass a function as the second argument to String.replace:
var replacements = [];
var newString = oldString.replace(/*regex pattern here*/, function(match){
replacements.push(match);
return 'some replacement string';
});
Javascript's replace lets us pass a function, so we can collect the matched values:
var arr = []
string.replace(/SSS.*?EEE/g, function (match) {
arr.push(match)
return '.*'
})
The .*? in the pattern insures it matches minimal length strings, and won't try to match from the first SSS to the last EEE.

Javascript regular expression to capture characters

I have written the following regexp in Javascript:
var rule = /^<[a-zA-Z0-9].*>/;
And the I checked it against this string:
var str = "<string stringValue><string2 stringValue>";
And the I executed:
var res = rule.exec(str);
And the res retruns:
<string stringValue> <string2 stringValue2>
Everything works in the way I need. But I must change two things:
1- First capture each occurrence (i mean each block of tag, in my example there are two)
2- I should strip off the tags [<>] in returned value. Is it then possible?
Regular expressions are, by default, "greedy". The .* in your rule will match as many characters as possible while still succeeding. Also, since you used ^ at the start, your pattern would only match the tag at the start of your input. This is why you are matching too much currently.
/<([^>]*)>/
Will match either tag, and put the contents (without the < >) in a capture group.
To find every tag, you can run the regular expression multiple times. Adding /g to the end makes the expression global, which allows for this behaviour.
var rule = /<([^>]*)>/g,
match,
tags = [],
input = "<string stringValue><string2 stringValue>";
while (match = rule.exec(input)) {
tags.push(match[1]);
}
console.log(tags);
In each loop, match[1] refers to the first capture group, the parentheses in the expression.
It will return:
[ "string stringValue", "string2 stringValue" ]
I guess you want to get the key value pair.
Try the code below:
var rule = /<([a-zA-Z0-9]*)\s+([a-zA-Z0-9]*)>/g;
var str = "<string stringValue><string2 stringValue>";
var res;
while((res = rule.exec(str)) !== null) {
console.log("key: "+res[1]+" value: "+res[2]);
}
//output
//key: string value: stringValue
//key: string2 value: stringValue
Try like this:
var reg = /<[a-zA-Z0-9][^>]*>/g;
var str = "<string stringValue><string2 stringValue>";
var res = str.match(reg);
res = res ? res.map(function(i){return i.replace(/^<|>$/g, '')}) : res;
// res[0]: string value: stringValu
// res[1]: string2 value: stringValue
Good luck!

Categories

Resources