Select certain elements from an array using javascript - javascript

I'm trying to extract user IDs from a form serialized string, here is what I have so far.
Take
var dataString = "viewUsers_length=10&id%5B%5D=8163&id%5B%5D=8188&id%5B%5D=8141"
as the example string.
I split it into an array like this
var arrStr = dataString.split(/[=&]/);
which results in an array
[0]viewUsers_length
[1]10
[2]id%5B%5D
[3]8163
[4]id%5B%5D
[5]8188
[6]id%5B%5D
[7]8141
But I only want the ids (8163, 8188, 8141)
in reality this string could contain thousands of ids in this format. I've spent some time googling so far and haven't found anything that I think will work.

Unfortunately because the parameter names for the ids are all the same, normal methods of parsing query strings might not be viable. So, this might be a job for regular expressions!
var dataString = "viewUsers_length=10&id%5B%5D=8163&id%5B%5D=8188&id%5B%5D=8141";
var regex = /&id%5B%5D=(\d+)/g;
var match;
var matches = [];
while (match = regex.exec(dataString)) {
matches.push(match[1]);
}
console.log(matches)
var list = matches.join(', ');
document.getElementById('output').innerHTML = list;
<div id="output"></div>

There are a couple of ways to address this. The first way, that I would use, would be to match the ID's with regex.
var ids = dataString.match(/id%5B%5D=[0-9]+/g);
Which would result in
["id%5B%5D=8163", "id%5B%5D=8188", "id%5B%5D=8141"]
So now we have the values, but we only want the numeric parts of it. So let's use map to remove the rest
ids = ids.map(function (id) {
return id.replace('id%5B%5D=', '');
});
The other way would just be to filter on the array you already built, but you can see that you have the 10 in the second index, which would come back as a false positive, so I think this would provide a cleaner dataset

Filter the array.
There are native JavaScript ways using Array.prototype.filter()
var dataString = "viewUsers_length=10&id%5B%5D=8163&id%5B%5D=8188&id%5B%5D=8141"
var arrStr = dataString.split(/[=&]/);
var tester = /\d{4}/;
arrStr.filter(function (item) {
return tester.test(item);
});
/*
viewUsers_length
10
id%5B%5D
8163 -Match
id%5B%5D
8188 -Match
id%5B%5D
8141 -Match
*/
As well as jQuery ways using $().filter()

Try this
var dataString = "viewUsers_length=10&id%5B%5D=8163&id%5B%5D=8188&id%5B%5D=8141";
var myRegexp = /id%5B%5D=([0-9]+)/g;
match = myRegexp.exec(dataString);
while (match != null) {
console.log(match[1]);
match = myRegexp.exec(ddd);
}
outputs
8163
8188
8141

I would split on the "&" characters, then map a function to remove everything before the "=", and finally filter to remove elements that aren't id elements. My substring function is a bit crude, and could be improved (or replaced with regex) with more knowledge of the possible values.
dataString
.split("&")
.map(function(elt){return elt.startsWith("id") ? elt.substring(9,13) : ""})
.filter(function(elt){return elt != ""})

Related

Finding multiple groups in one string

Figure the following string, it's a list of html a separated by commas. How to get a list of {href,title} that are between 'start' and 'end'?
not thisstartfoo, barendnot this
The following regex give only the last iteration of a.
/start((?:<a href="(?<href>.*?)" title="(?<title>.*?)">.*?<\/a>(?:, )?)+)end/g
How to have all the list?
This should give you what you need.
https://regex101.com/r/isYIeR/1
/(?:start)*(?:<a href=(?<href>.*?)\s+title=(?<title>.*?)>.*?<\/a>)+(?:,|end)
UPDATE
This does not meet the requirement.
The Returned Value for a Given Group is the Last One Captured
I do not think this can be done in one regex match. Here is a javascript solution with 2 regex matches to get a list of {href, title}
var sample='startfoo, bar,barendstart<img> something end\n' +
'beginfoo, bar,barend\n'+
'startfoo again, bar again,bar2 againend';
var reg = /start((?:\s*<a href=.*?\s+title=.*?>.*?<\/a>,?)+)end/gi;
var regex2 = /href=(?<href>.*?)\s+title=(?<title>.*?)>/gi;
var step1, step2 ;
var hrefList = [];
while( (step1 = reg.exec(sample)) !== null) {
while((step2 = regex2.exec(step1[1])) !== null) {
hrefList.push({href:step2.groups["href"], title:step2.groups["title"]});
}
}
console.log(hrefList);
If the format is constant - ie only href and title for each tag, you can use this regex to find a string which is not "", and has " and a space or < after it using lookahead (regex101):
const str = 'startfoo, barend';
const result = str.match(/[^"]+(?="[\s>])/gi);
console.log(result);
This regex:
<.*?>
removes all html tags
so for example
<h1>1. This is a title </h1><ul><a href='www.google.com'>2. Click here </a></ul>
After using regex you will get:
1. This is a title 2. Click here
Not sure if this answers your question though.

Split text with a single code

var objname = "Image1-123456-789.png"
quick question i wanted to split this text without match them together again.
here is my code
var typename = objname.split("-");
//so it will be Image1,123456,789.png
var SplitNumber = typename[1]+'-'+typename[2];
var fullNumber = SplitCode.split('.')[0];
to get what i wanted
my intention is to get number is there anyway i can split them without join them and split again ?
can a single code do that perfectly ? my code look like so many job.
i need to get the 123456-789.
The String.prototype.substring() method extracts the characters from a string, between two specified indices, and returns the new sub string.
This method extracts the characters in a string between "start" and "end", not including "end" itself.
var objname = "Image1-123456-789.png";
var newname = objname.substring(objname.indexOf("-")+1, objname.indexOf("."));
alert(newname);
An alternate can be using Join. You can use slice to fetch range of values in array and then join them using -.
var objname = "Image1-123456-789.png";
var fullnumber = objname.split("-").slice(1).join("-").split(".")[0];
alert(fullnumber)
Reference
Join Array from startIndex to endIndex
Here is your solution
var objname = "Image1-123456-789.png";
var typename= objname.split("-");
var again=typename[2];
var again_sep= again.split(".");
var fullNumber =typename[1]+'-'+again_sep[0];

Regular expression in Javascript: table of positions instead of table of occurrences

Regular expressions are most powerful. However, the result they return is sometimes useless:
For example:
I want to manage a CSV string using semicolons.
I define a string like:
var data = "John;Paul;Pete;Stuart;George";
If I use the instruction:
var tab = data.match(/;/g)
after what, "tab" contains an array of 4 ";" :
tab[0]=";", tab[1]=";", tab[2]=";", tab[3]=";"
This array is not useful in the present case, because I knew it even before using the regular expression.
Indeed, what I want to do is 2 things:
1stly: Suppress the 4th element (not "Stuart" as "Stuart", but "Stuart" as 4th element)
2ndly: Replace the 3rd element by "Ringo" so as to get back (to where you once belonged!) the following result:
data == "John;Paul;Ringo;George";
In this case, I would greatly prefer to obtain an array giving the positions of semicolons:
tab[0]=4, tab[1]=9, tab[2]=14 tab[3]=21
instead of the useless (in this specific case)
tab[0]=";", tab[1]=";", tab[2]=";", tab[3]=";"
So, here's my question: Is there a way to obtain this numeric array using regular expressions?
To get tab[0]=4, tab[1]=9, tab[2]=14 tab[3]=21, you can do
var tab = [];
var startPos = 0;
var data = "John;Paul;Pete;Stuart;George";
while (true) {
var currentIndex = data.indexOf(";", startPos);
if (currentIndex == -1) {
break;
}
tab.push(currentIndex);
startPos = currentIndex;
}
But if the result wanted is "John;Paul;Ringo;George", you can do
var tab = data.split(';'); // Split the string into an array of strings
tab.splice(3, 1); // Suppress the 4th element
tab[2] = "Ringo"; // Replace the 3rd element by "Ringo"
var str = tab.join(';'); // Join the elements of the array into a string
The second approach is maybe better in your case.
String.split
Array.splice
Array.join
You should try a different approach, using split.
tab = data.split(';') will return an array of the form
tab[0]="John", tab[1]="Paul", tab[2]="Pete", tab[3]="Stuart", tab[4]="George"
You should be able to achieve your goal with this array.
Why use a regex to perform this operation? You have a built-in function split, which can split your string based on the delimiter you pass.
var data = "John;Paul;Pete;Stuart;George";
var temp=data.split(';');
temp[0],temp[1]...

How to remove the last matched regex pattern in javascript

I have a text which goes like this...
var string = '~a=123~b=234~c=345~b=456'
I need to extract the string such that it splits into
['~a=123~b=234~c=345','']
That is, I need to split the string with /b=.*/ pattern but it should match the last found pattern. How to achieve this using RegEx?
Note: The numbers present after the equal is randomly generated.
Edit:
The above one was just an example. I did not make the question clear I guess.
Generalized String being...
<word1>=<random_alphanumeric_word>~<word2>=<random_alphanumeric_word>..~..~..<word2>=<random_alphanumeric_word>
All have random length and all wordi are alphabets, the whole string length is not fixed. the only text known would be <word2>. Hence I needed RegEx for it and pattern being /<word2>=.*/
This doesn't sound like a job for regexen considering that you want to extract a specific piece. Instead, you can just use lastIndexOf to split the string in two:
var lio = str.lastIndexOf('b=');
var arr = [];
var arr[0] = str.substr(0, lio);
var arr[1] = str.substr(lio);
http://jsfiddle.net/NJn6j/
I don't think I'd personally use a regex for this type of problem, but you can extract the last option pair with a regex like this:
var str = '~a=123~b=234~c=345~b=456';
var matches = str.match(/^(.*)~([^=]+=[^=]+)$/);
// matches[1] = "~a=123~b=234~c=345"
// matches[2] = "b=456"
Demo: http://jsfiddle.net/jfriend00/SGMRC/
Assuming the format is (~, alphanumeric name, =, and numbers) repeated arbitrary number of times. The most important assumption here is that ~ appear once for each name-value pair, and it doesn't appear in the name.
You can remove the last token by a simple replacement:
str.replace(/(.*)~.*/, '$1')
This works by using the greedy property of * to force it to match the last ~ in the input.
This can also be achieved with lastIndexOf, since you only need to know the index of the last ~:
str.substring(0, (str.lastIndexOf('~') + 1 || str.length() + 1) - 1)
(Well, I don't know if the code above is good JS or not... I would rather write in a few lines. The above is just for showing one-liner solution).
A RegExp that will give a result that you may could use is:
string.match(/[a-z]*?=(.*?((?=~)|$))/gi);
// ["a=123", "b=234", "c=345", "b=456"]
But in your case the simplest solution is to split the string before extract the content:
var results = string.split('~'); // ["", "a=123", "b=234", "c=345", "b=456"]
Now will be easy to extract the key and result to add to an object:
var myObj = {};
results.forEach(function (item) {
if(item) {
var r = item.split('=');
if (!myObj[r[0]]) {
myObj[r[0]] = [r[1]];
} else {
myObj[r[0]].push(r[1]);
}
}
});
console.log(myObj);
Object:
a: ["123"]
b: ["234", "456"]
c: ["345"]
(?=.*(~b=[^~]*))\1
will get it done in one match, but if there are duplicate entries it will go to the first. Performance also isn't great and if you string.replace it will destroy all duplicates. It would pass your example, but against '~a=123~b=234~c=345~b=234' it would go to the first 'b=234'.
.*(~b=[^~]*)
will run a lot faster, but it requires another step because the match comes out in a group:
var re = /.*(~b=[^~]*)/.exec(string);
var result = re[1]; //~b=234
var array = string.split(re[1]);
This method will also have the with exact duplicates. Another option is:
var regex = /.*(~b=[^~]*)/g;
var re = regex.exec(string);
var result = re[1];
// if you want an array from either side of the string:
var array = [string.slice(0, regex.lastIndex - re[1].length - 1), string.slice(regex.lastIndex, string.length)];
This actually finds the exact location of the last match and removes it regex.lastIndex - re[1].length - 1 is my guess for the index to remove the ellipsis from the leading side, but I didn't test it so it might be off by 1.

Extracting number ID from a URL in Javascript

Similar to my previous question:
spliting a string in Javascript
The URLs have now changed and the unique number ID is no longer at the end of the URL like so:
/MarketUpdate/Pricing/9352730/Report
How would i extract the number from this now i cannot use the previous solution?
You could search for
/(\d+)/
and use backreference no. 1 which will contain the number. Note that this requires the number to always be delimited by slashes on both sides. If you also want to match numbers at the end of the string, use
/(\d+)(?:/|$)
In JavaScript:
var myregexp = /\/(\d+)\//;
// var my_other_regexp = /\/(\d+)(?:\/|$)/;
var match = myregexp.exec(subject);
if (match != null) {
result = match[1];
} else {
result = "";
}
If the URLs always look like that, why not use split() ?
var ID = url.split('/')[3];
urlstring = "/MarketUpdate/Pricing/9352730/Report"
$str = urlstring.split("/");
alert($str[3]);
This splits the string each time it finds the / symbol and stores it into an array, You can then get each word in the array by using $str[0]

Categories

Resources