Hi I am new for Regex and trying to get below,
there is a string below in javascript,
"function(){var a; var a,b,c;}"
and I am trying to find [a,b,c] from it.
Please suggest me to get all variable declared in string, what will be regex.
A very very manipulative solution, but will serve your purpose
function uniq(value,index,self){
return self.indexOf(value) === index;
}
var str = "function(){var a; var a,b,c;}";
var ptrn = /var [^;]+/g;
var match;
var matches = []
while ( ( match = ptrn.exec(str) ) != null )
{
matches.push(match.join().split(" ")[1]);
}
console.log(matches.join(",").split(",").filter(uniq));
but if you understand this code you wont have to ever search for:
how to get unique values from js array
how matching a pattern with exec only returns the first match and we have to loop to get the rest of the values
finally adding a filter with a function.
Related
I have this json
var json = {
"I:5.3": {
"conf": {
"name": "Jack"
}
}
}
and this string
var str = '["I.5.3"]["conf"]'
How can get str value from json like
json["I.5.3"]["conf"]
I have json object and str and I have to extract something like
json[str] = json["I.5.3"]["conf"]
Your title suggests you would like to get:
The value of a string.
Which has a list of Array's.
From a JSON object.
However, all your code shows is a Plain JavaScript object. No arrays to be seen... and the only string value I can find is "Jack".
Jack would be extracted like, json["I.5.3"]["conf"]["name"].
Or via dot notation =>
const obj = json["I.5.3"];
const nameValue = obj.conf.name; // => Jack
You have 2 ways(at least that's what's in coming through my mind now):
1st way
var json = {
"I:5.3": {
"conf": {
"name": "Jack"
}
}
}
var str = '["I:5.3"]["conf"]'
var scr_line = 'json'+str;
var target = eval(scr_line);
console.log(target);
2nd way:
var json = {
"I:5.3": {
"conf": {
"name": "Jack"
}
}
}
var str = '["I:5.3"]["conf"]';
let ret = getVal(json, str);
console.log(ret);
function getVal(obj, path){
var regex = /\["(.*?)"\]/mg;
let m;
while ((m = regex.exec(path)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
if(typeof obj[m[1]] !== 'undefined') obj = obj[m[1]];
else return obj[m[1]];
}
return obj;
}
I would prefer the second because it checks if the property on the object exists
You would have to split the string up into separate parts, I believe.
var str = '["I.5.3"]["conf"]';
var identifiers = str.split('][');
// identifiers would be an array like:
// ["I.5.3", "conf"]
var person = json[identifiers[0]][identifiers[1]];
// person = {
// "name": "Jack"
// }
String.prototype.split() allows you to separate parts of a string out into an array. Checkout the MDN docs to learn more about that particular method.
This specific answer expects that there will always be the properties you split, though and will error out if one is missing. For something a little safer, I would suggest checking to see if that object contains the property you're expecting before trying to access it.
var str = '["I.5.3"]["conf"]';
var identifiers = str.split('][');
try {
var myVal;
// Let's check if the property exists.
if (Object.prototype.hasOwnProperty.call(json, identifiers[0]){
myVal = json[identifiers[0]];
if (Object.prototype.hasOwnProperty.call(myVal, identifiers[1]){
myVal = myVal[identifiers[1]];
}
}
} catch(error) {
// One of the properties didn't exist or something went wrong in the try
// block above.
}
EDIT:
The follow would format your string specifically to meet the match to become an array. If there were single quotes or double quotes anywhere in each array item, this would fall through, so be aware of that.
var myArray = str.slice(2, -2).split('][').map(function(item) {
return item.replace('"', '');
});
String.prototype.slice() extracts a section of a string and returns it as a new string, without modifying the original string.
Then the split method separates it into different array items. Then we iterate over each item in the array and remove additional ". Just to say again, this will fall apart if the original string looks like ['one']['two']. This would also not be reliable if the string looks like ["can't"]["won't"]. So just be aware of that in your particular case. If you're positive that the string will always meet the format you have above, then you can rely on this.
When I use the console.log( ) function to join this array it returns the combined array, but when I use the .join( ) function outside of console.log( ), it does not combine the array. How do I combine this array to create a single string with no comma outside of console.log( )?
var string = stringArray.map(string => "&sources=" + string);
console.log(stringURL.join(''));
stringURL.join('');
console.log(stringURL);
.join() is a function that returns the joined string. So when you call it, it calculates the value and then returns it.
Store it in a variable.
var joinedString = stringURL.join('');
Your problem is that stringURL.join(''); does modify stringURL but give a new string. so the best is to make
var new_string = stringURL.join('');
console.log(new_string);
You can't have a variable name called string, it's protected. Change it to something else and it will work.
Here's a complete list of reserved keywords and here is an explanation from Mozilla MDN
var mappedString = stringArray.map(string => "&sources=" + string);
console.log(mappedString.join(''));
var joinedString = mappedString.join('')
console.log(joinedString);
That should do!
Note: I changed the title of the question, as well as all reference to JSON so that the question better reflects my problem. I got several times the advice of "better iterate the object than work on a serialized version" but I believe (and am certainly mistaken and wrong) that searching for a well-defined pattern in a string is easier than go for iterative or recursive code to iterate an object
I need to extract the pattern "something":"thestring" from a string.
The source string will have many other combinations such as "something":[{"thestring":{"key":18,"anotherkey":"astring"}}], from which only the pair "anotherkey":"astring" is sought for.
I am specifically interested in getting the content of the value, that is thestring in the first example (and astring in the second one).
I tried to match ".*?","(.*?)" but I get more than just the pair, matching the comma after the quote (and it goes downhill form there).
An example of a test string and my failed test is on Regex101
Here is how I would write this:
function extractStrings(obj) {
var stringSet = [];
function extractStringsHelper(obj) {
if (typeof obj === 'string' && stringSet.indexOf(obj) === -1) {
stringSet.push(obj);
} else if (typeof obj === 'array') {
for (var i=0; i<obj.length; i++) {
extractStringsHelper(obj);
}
} else if (typeof obj === 'object' && obj !== null) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
extractStringsHelper(obj[key]);
}
}
}
}
extractStringsHelper(obj);
return stringSet;
}
> extractStrings({'a': "strA", 'b': ["strB1", 1, "strB2", {'n': "strC"}]})
> (4) ["strA", "strB1", "strB2", "strC"]
You can also go the regex route and look for:
"[^"]+":"([^"]+)"
Here is your example with the modified regex: https://regex101.com/r/uxS9k0/2
But this path is dark and full of terrors. For example, it breaks if the string contains an escaped double quote. Once you start accounting for all the possible cases, you are basically rewriting a JSON tokenizer.
Try this regex :
If you really want to work on a string, this regex will do what you want, as long as what you look for is always between quotes and preceded by a key between quotes :
"\w+":"(\w+)"
Demo here
The value will be captured in group 1
Here is how to get your value :
var regex = /"\w+":"(\w+)"/g;
var json = "\"something\":\"thestring\"\n\"something\":[{\n\t\"thestring\":{\n\t\t\"key\":18,\n\t\t\"anotherkey\":\"astring\"\n\t}\n}]";
console.log(json);
var match = regex.exec(json);
for (i = 1; match != null; i++) { // You need to loop until you match every value
// Full match is in match[0]
// Your value is in match[1]
console.log("Val"+i+": "+match[1])
match = regex.exec(json);
}
If you are working with valid json you shouldn't need to use regex, and can deserialize it with the following:
var data = JSON.parse(json_string);
I currently have the following function, which works:
String.prototype.matchAny = function(patterns) {
var that = this;
var matched = false;
// Iterate patterns and return key of first match
$.each(patterns, function(i, v) {
if (that.match(v)) {
matched = i;
return false;
}
});
return matched;
};
It will return the index in patterns of the first matched regular expression for the string. For example:
"blah".matchAny([/a/, /z/]); // 0
"blah".matchAny({z: /z/, a: /a/]); // "a"
However, this solution feels clunky to me. I've had some success using Array.some(), and while it's a lot more elegant, I can't find a way to get the result I want (return the key from patterns that matched).
Is there something I'm missing? More specifically, is there a built-in function (JavaScript/jQuery) that can produce the same results?
I have the following situation:
There is a certain string that contains some vars, such as:
var string = '/page/{id}/{title}';
Now, I want to be able to replace {id} and {title} with the vars from the following array:
var arr = {'id':10, 'title':'test-page'};
I came up with this little regex:
string.replace ( /{([a-zA-Z0-9]+)}/g , '$1' );
Which, as expected, just returns this:
/page/id/title
So I tried this:
string.replace ( /{([a-zA-Z0-9]+)}/g , arr [ '$1' ] );
But that returns a
/page/undefined/undefined
Now, I understand that something like this would be possible with a loop et cetera, but it would be nice to have a one-liner for this. I am not very used to JS, so I hope that there is some function or option that I am unaware of that helps me out with this :).
Best regards!
Try something like this:
var arr = {'id':10, 'title':'test-page'};
'/page/{id}/{title}'.replace(/\{([\w\d]+?)\}/g, function(a, b) {
return arr[b] || '';
});
If you use this replace thing often I would create a String helper prototype method. For example:
String.prototype.template = function(data) {
return this.replace(/\{([\w\d]+?)\}/g, function(a, b) {
return data[b] || '';
});
};
and use it like this:
'/page/{id}/{title}'.template(arr);
According to MDN article,
Because we want to further
transform the result of the match before the final substitution is
made, we must use a function. This forces the evaluation of the match
prior to the toLowerCase() method. If we had tried to do this using
the match without a function, the toLowerCase() would have no effect.
(In the text above, replace toLowerCase() with "accessing property in object")
Then, you can use
function replacer(match, p1, p2, p3/*, ...*/, offset, string){
return arr[p1];
}
var arr = {'id':10, 'title':'test-page'};
'/page/{id}/{title}'.replace(/\{([\w\d]+?)\}/g, replacer);