pretty complex Regex - javascript

I did a lot of research, but apparently my Regex skills are not enough to solve this, so I come to humbly ask for advice.
I have a JS var that gets strings similar to this:
"value=8kadctgwqqe0&value=8kaczvfgoyrs&value=8kwkgz2ysm1i"
it doesn't have a fixed lenght. it may return 1 or 20 values, there's no way to know.
As you can see, it returns a big sequence of values that are always between "value=" and "&", except for the last one, that has no "&" in the end.
I need to parse that, and get this in the end:
8kadctgwqqe0
8kaczvfgoyrs
8kwkgz2ysm1i
I don't even know where to start...
Thanks a lot!

personally I would avoid regex for this.
if your string is always in the value=SOMETHING&value=SOMETHINGELSE format use this
string.split("value=").join("").split("&")
according to How to replace all occurrences of a string in JavaScript? its actually quicker to use this over regex also
var string = "value=8kadctgwqqe0&value=8kaczvfgoyrs&value=8kwkgz2ysm1i"
var yourArray = string.split("value=").join("").split("&")
["8kadctgwqqe0", "8kaczvfgoyrs", "8kwkgz2ysm1i"]
You may need to add some tests to ensure the correct format of string if you are not sure about it.

The following RegExp/.filter() should do it:
'value=8kadctgwqqe0&value=8kaczvfgoyrs&value=8kwkgz2ysm1i'.match(/([^=&]+)/g).filter(function(a){return a!='value'});
The .match() will grab the separate query values (and the key names). In order to deal with this, we use .filter() to remove the value results. This will leave it with the correct results.
Sometimes it's better to use regular JavaScript string manipulation (even though this looks like the worst answer)
.filter() is awesome, more info on it here

You can use the following regex:
/(?:^|&)value=([^&]*)/g
regex101 demo
The matches are then stored in the first capture group.
You can now access the capture groups using this method:
var myRegexp = /(?:^|&)value=([^&]*)/g;
var myString = "value=8kadctgwqqe0&value=8kaczvfgoyrs&value=8kwkgz2ysm1i";
match = myRegexp.exec(myString);
while (match != null) {
console.log(match[1]);
match = myRegexp.exec(myString);
}
If you are interested in the keys as well, you can use:
/(?:^|&)([^=&]*)=([^&]*)/g
In that case for each iteration, the key can be found in the first match, and the value in the second one:
var myRegexp = /(?:^|&)([^&=]*)=([^&]*)/g;
var myString = "value=8kadctgwqqe0&value=8kaczvfgoyrs&value=8kwkgz2ysm1i";
match = myRegexp.exec(myString);
while (match != null) {
console.log(match[1]); //key
console.log(match[2]); //value
match = myRegexp.exec(myString);
}

This works as well:
str.match(/value=([^&]*)/g).join("").split('value=').splice(1)

Related

How to split a string by a character not directly preceded by a character of the same type?

Let's say I have a string: "We.need..to...split.asap". What I would like to do is to split the string by the delimiter ., but I only wish to split by the first . and include any recurring .s in the succeeding token.
Expected output:
["We", "need", ".to", "..split", "asap"]
In other languages, I know that this is possible with a look-behind /(?<!\.)\./ but Javascript unfortunately does not support such a feature.
I am curious to see your answers to this question. Perhaps there is a clever use of look-aheads that presently evades me?
I was considering reversing the string, then re-reversing the tokens, but that seems like too much work for what I am after... plus controversy: How do you reverse a string in place in JavaScript?
Thanks for the help!
Here's a variation of the answer by guest271314 that handles more than two consecutive delimiters:
var text = "We.need.to...split.asap";
var re = /(\.*[^.]+)\./;
var items = text.split(re).filter(function(val) { return val.length > 0; });
It uses the detail that if the split expression includes a capture group, the captured items are included in the returned array. These capture groups are actually the only thing we are interested in; the tokens are all empty strings, which we filter out.
EDIT: Unfortunately there's perhaps one slight bug with this. If the text to be split starts with a delimiter, that will be included in the first token. If that's an issue, it can be remedied with:
var re = /(?:^|(\.*[^.]+))\./;
var items = text.split(re).filter(function(val) { return !!val; });
(I think this regex is ugly and would welcome an improvement.)
You can do this without any lookaheads:
var subject = "We.need.to....split.asap";
var regex = /\.?(\.*[^.]+)/g;
var matches, output = [];
while(matches = regex.exec(subject)) {
output.push(matches[1]);
}
document.write(JSON.stringify(output));
It seemed like it'd work in one line, as it did on https://regex101.com/r/cO1dP3/1, but had to be expanded in the code above because the /g option by default prevents capturing groups from returning with .match (i.e. the correct data was in the capturing groups, but we couldn't immediately access them without doing the above).
See: JavaScript Regex Global Match Groups
An alternative solution with the original one liner (plus one line) is:
document.write(JSON.stringify(
"We.need.to....split.asap".match(/\.?(\.*[^.]+)/g)
.map(function(s) { return s.replace(/^\./, ''); })
));
Take your pick!
Note: This answer can't handle more than 2 consecutive delimiters, since it was written according to the example in the revision 1 of the question, which was not very clear about such cases.
var text = "We.need.to..split.asap";
// split "." if followed by "."
var res = text.split(/\.(?=\.)/).map(function(val, key) {
// if `val[0]` does not begin with "." split "."
// else split "." if not followed by "."
return val[0] !== "." ? val.split(/\./) : val.split(/\.(?!.*\.)/)
});
// concat arrays `res[0]` , `res[1]`
res = res[0].concat(res[1]);
document.write(JSON.stringify(res));

Regex one-liner for splitting string at nth character where n is a variable length

I've found a few similar questions, but none of them are clean one-liners, which I feel should be possible. I want to split a string at the last instance of specific character (in my case .).
var img = $('body').attr('data-bg-img-url'); // the string http://sub.foo.com/img/my-img.jpg
var finalChar = img.split( img.split(/[.]+/).length-1 ); // returns int 3 in above string example
var dynamicRegex = '/[.$`finalChar`]/';
I know I'm breaking some rules here, wondering if someone smarter than me knows the correct way to put that together and compress it?
EDIT - The end goal here is to split and store http://sub.foo.com/img/my-img and .jpg as separate strings.
In regex, .* is greedy, meaning it will match as much as possible. Therefore, if you want to match up to the last ., you could do:
/^.*\./
And from the looks, you are trying to get the file extension, so you would want to add capture:
var result = /^.*\.(.*)$/.exec( str );
var extension = result[1];
And for both parts:
var result = /^(.*)\.(.*)$/.exec( str );
var path = result[1];
var extension = result[2];
You can use the lastIndexOf() method on the period and then use the substring method to obtain the first and second string. The split() method is better used in a foreach scenario where you want to split at all instances. Substring is preferable for these types of cases where you are breaking at a single instance of the string.

How to read all string inside parentheses using regex

I wanted to get all strings inside a parentheses pair. for example, after applying regex on
"fun('xyz'); fun('abcd'); fun('abcd.ef') { temp('no'); "
output should be
['xyz','abcd', 'abcd.ef'].
I tried many option but was not able to get desired result.
one option is
/fun\((.*?)\)/gi.exec("fun('xyz'); fun('abcd'); fun('abcd.ef')").
Store the regex in a variable, and run it in a loop...
var re = /fun\((.*?)\)/gi,
string = "fun('xyz'); fun('abcd'); fun('abcd.ef')",
matches = [],
match;
while(match = re.exec(string))
matches.push(match[1]);
Note that this only works for global regex. If you omit the g, you'll have an infinite loop.
Also note that it'll give an undesired result if there a ) between the quotation marks.
You can use this code will almost do the job:
"fun('xyz'); fun('abcd'); fun('abcd.ef')".match(/'.*?'/gi);
You'll get ["'xyz'", "'abcd'", "'abcd.ef'"] which contains extra ' around the string.
The easiest way to find what you need is to use this RegExp: /[\w.]+(?=')/g
var string = "fun('xyz'); fun('abcd'); fun('abcd.ef')";
string.match(/[\w.]+(?=')/g); // ['xyz','abcd', 'abcd.ef']
It will work with alphanumeric characters and point, you will need to change [\w.]+ to add more symbols.

Javascript regex match for string "game_1"

I just can't get this thing to work in javascript. So, I have a text "game_1" without the quotes and now i want to get that number out of it and I tried this:
var idText = "game_1";
re = /game_(.*?)/;
found = idText.match(re);
var ajdi = found[1];
alert( ajdi );
But it doesn't work - please point out where am I going wrong.
If you're only matching a number, you may want to try
/game_([0-9]+)/
as your regular expression. That will match at least one number, which seems to be what you need. You entered a regexp that allows for 0 characters (*) and let it select the shortest possible result (?), which may be a problem (and match you 0 characters), depending on the regex engine.
If this is the complete text, then there is no need for regular expressions:
var id = +str.split('_')[1];
or
var id = +str.replace('game_', '');
(unary + is to convert the string to a number)
If you insist on regular expression, you have to anchor the expression:
/^game_(.*?)$/
or make the * greedy by omitting the ?:
/game_(.*)/
Better is to make the expression more restrictive as #Naltharial suggested.
Simple string manipulation:
var idText = "game_1",
adji = parseInt(idText.substring(5), 10);
* means zero or more occurrences. It seems that combining it with a greediness controller ? results in zero match.
You could replace * with + (which means one or more occurrences), but as #Felix Kling notes, it would only match one digit.
Better to ditch the ? completely.
http://jsfiddle.net/G8Qt7/2/
Try "game_1".replace(/^(game_)/, '')
this will return the number
You can simply use this re /\d+/ to get any number inside your string

JavaScript match substring after RegExp

I have a string that look something like
something30-mr200
I would like to get everything after the mr (basically the # followed by mr) *always there is going to be the -mr
Any help will be appreciate it.
You can use a regexp like the one Bart gave you, but I suggest using match rather than replace, since in case a match is not found, the result is the entire string when using replace, while null when using match, which seems more logical. (as a general though).
Something like this would do the trick:
function getNumber(string) {
var matches = string.match(/-mr([0-9]+)/);
return matches[1];
}
console.log(getNumber("something30-mr200"));
var result = "something30-mr200".split("mr")[1];
or
var result = "something30-mr200".match(/mr(.*)/)[1];
Why not simply:
-mr(\d+)
Then getting the contents of the capture group?
What about:
function getNumber(input) { // rename with a meaningful name
var match = input.match(/^.*-mr(\d+)$/);
if (match) { // check if the input string matched the pattern
return match[1]; // get the capturing group
}
}
getNumber("something30-mr200"); // "200"
This may work for you:
// Perform the reg exp test
new RegExp(".*-mr(\d+)").test("something30-mr200");
// result will equal the value of the first subexpression
var result = RegExp.$1;
What about finding the position of -mr, then get the substring from there + 3?
It's not regex, but seems to work given your description?

Categories

Resources