JavaScript find string in string between 2 words - javascript

I have strings as below.
/edit/120/test or /edit/120/test1, ... etc
I want to find 120 or from the string like that, How can I find that with javascript.

As David said, there are a few ways to do this. Given that the string you are looking for is always between "/edit/" and "/" followed by any text, here is how I would do it :
var target = "/edit/120/test" // for example
var result = target.substring(6) // removes the first 6 characters ("/edit/")
.split('/') // produces the following array : [120, test]
[0] // the first element of the array ("120")
Actually, let's be honest, I'm too lazy for that. Here's how I'd really do it :
var target = "/edit/120/test" // for example+
var result = target.split('/')[2]; // takes the 3rd element of the following array : ['', 'edit', '120', 'test']

Related

Extract part of URL with Regex

I have a URL that will always be in either this format
http://domain.tld/foo/bar/boo
http://www.domain.tld/foo/bar/boo
http://sub.domain.tld/foo/bar/boo
http://www.sub.domain.tld/foo/bar/boo
I'd like to use Regex to extract bar from the url, regardless of the format.
I am using JavaScript.
I tried to break the url up using something like
var x = 'http://domain.tld/foo/bar/boo`'
x.split(/^((http[s]?):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$/g)
but this doesn't really work nor does it help as I seem to get an array or items when I really just need the value at bar
var el = document.createElement('a');
el.href = "http://www.domain.tld/foo/bar/boo";
var importantPart = el.pathname.split('/')[2];
console.log(importantPart);
fiddle: https://jsfiddle.net/dcyo4ph5/1/
sources: https://css-tricks.com/snippets/javascript/get-url-and-url-parts-in-javascript/ & JavaScript - Get Portion of URL Path
I guess this doesn't use regex. So that's maybe not what you want.
I'll list both regex and non regex way. Surprisingly the regex way seems shorter.
Regex Way
The regex to find bar and boo is this /.*\/(.*)\/(.*)$/ which is short, precise and exactly what you need.
Let's put into practice,
const params = "http://www.sub.domain.tld/foo/bar/boo".match(/.*\/(.*)\/(.*)$/)
This results in,
params;
["http://www.sub.domain.tld/foo/bar/boo","bar","boo"]
Just access it like params[0] and params[1].
Regex Explanation:
Extended Version:
The regex can be extended more to grab the /bar/foo/ pattern with a ending slash like this,
.*\/\b(.*)\/\b(.*)(\/?)$
Which means,
and it can be further extended, but let's keep it simple for now.
Non Regex Way
Use native methods like .split(),
function getLastParam(str, targetIndex = 1) {
const arr = str
.split("/") // split by slash
.filter(e=>e); // remove empty array elements
return arr[arr.length - targetIndex];
}
Let's test it out quickly for different cases
[
"http://domain.tld/foo/bar/boo",
"http://www.domain.tld/foo/bar/boo",
"http://sub.domain.tld/foo/bar/boo",
"http://www.sub.domain.tld/foo/bar/boo",
"http://domain.tld/foo/bar/boo/",
".../bar/boo"
].map(e => {
console.log({ input: e, output: getLastParam(e, 1) });
});
This will yield in following,
{input: "http://domain.tld/foo/bar/boo", output: "boo"}
{input: "http://www.domain.tld/foo/bar/boo", output: "boo"}
{input: "http://sub.domain.tld/foo/bar/boo", output: "boo"}
{input: "http://www.sub.domain.tld/foo/bar/boo", output: "boo"}
{input: "http://domain.tld/foo/bar/boo/", output: "boo"}
{input: ".../bar/boo", output: "boo"}
If you want bar, then use 2 for targetIndex instead. It will get the second last. In which case, getLastParam(str, 2) would result in bar.
Speed stuff
Here is the small benchmark stuff, http://jsbench.github.io/#a6bcecaa60b7d668636f8f760db34483
getLastParamNormal: 5,203,853 ops/sec
getLastParamRegex: 6,619,590 ops/sec
Well, it doesn't matter. But nonetheless, it's interesting.
Split and slice will do that as simple as this, where split('/') creates an array and slice(-2)[0] will pick the first [0] of the last two (-2).
With replace(/\/$/, "") you get rid of any trailing slash (showed in 4th sample below)
Stack snippet
var x = 'http://domain.tld/foo/bar/boo'
console.log( x.split('/').slice(-2)[0] );
var x = 'http://www.sub.domain.tld/foo/bar/boo'
console.log( x.split('/').slice(-2)[0] );
var x = 'http://www.domain.tld/foo/bar/boo'
console.log( x.split('/').slice(-2)[0] );
// and this one will trim trailing slash
var x = 'http://www.domain.tld/foo/bar/boo/'
console.log( x.replace(/\/$/, "").split('/').slice(-2)[0] );
Or maybe just reverse the array and get the 2nd item ([1] as array is zero based)
var x = 'http://www.domain.tld/foo/bar/boo/'
console.log( x.split('/').reverse()[1] );
You don't need regex. Anchor elements have an API that breaks down the URL for you. You can then split the pathname to get the path
function parse(path) {
let a = document.createElement('a');
a.href = path;
return a.pathname.split('/')[2];
}
console.log(parse('http://domain.tld/foo/bar/boo'));
console.log(parse('http://www.domain.tld/foo/bar/boo'));
console.log(parse('http://sub.domain.tld/foo/bar/boo'));
console.log(parse('http://www.sub.domain.tld/foo/bar/boo'));

regex to get all occurrences with optional next character or end of string

I have a string separated by forward slashes, and wildcards are denoted by beginning with a $:
/a/string/with/$some/$wildcards
I need a regex to get all wildcards (without the "$"), where wildcards can either have more "string" ahead of them (and the next character should always be a forward slash) or will be at the end of the string. Here is where I'm at (it matches to the end of the string rather to the next "/"):
//Just want to match $one
var string = "/a/string/with/$one/wildcard"
var re = /\$(.*)($|[/]?)/g
var m = re.exec(string)
console.log(m);
// [ '$one/wildcard',
// 'one/wildcard',
// '',
// index: 123,
// input: '/a/string/with/$one/wildcard'
// ]
Here was a previous attempt (that doesn't account for wildcards that are at the end of the string):
//Want to match $two and $wildcards
var string = "/a/string/with/$two/$wildcards"
var re = /\$(.*)\//g
var m = re.exec(string)
console.log(m);
// [ '$two/',
// 'two',
// '',
// index: 123,
// input: '/a/string/with/$two/$wildcards'
// ]
I've searched around for matching a character or end of string and have found several answers, but none that try to account for multiple matches. I think I need the ability to match the next character as a / greedily, and then try to match the end of the string.
The desired functionality is to take the input string:
/a/string/with/$two/$wildcards
and transform it to the following:
/a/string/with/[two]/[wildcards]
Thanks in advance! Also, apologies if this has been explicitly covered in detail, I was unable to find a replica after various searches.
I think this should do it:
/\$([^\/]+)/g
And the you can use the replace() function:
"/a/string/with/$two/$wildcards".replace(/\$([^\/]+)/g, "[$1]");
// "/a/string/with/[two]/[wildcards]"
You can use replace function on the string like so:
var s = '/a/string/with/$two/$wildcards';
s.replace(/\$([a-zA-Z]+)/g, '[$1]')';
s will have the value:
/a/string/with/[two]/[wildcards]
Here's a reference to replace documentation https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/replace

RegEx for filling up string

I have the following input:
123456_r.xyz
12345_32423_131.xyz
1235.xyz
237213_21_mmm.xyz
And now I need to fill up the first connected numbers to 8 numbers leading with 0:
00123456_r.xyz
00012345_32423_131.xyz
00001235.xyz
00237213_21_mmm.xyz
My try was to split a the dot, then split (if existing) at the underscore and get the first numbers and fill them up.
But I think there will be a more efficient way with the regex replace function with just the one function, right? How would this look like?
TIA
Matt
I would use a regex, but just for the spliting :
var input = "12345_32423_131.xyz";
var output = "00000000".slice(input.split(/_|\./)[0].length)+input;
Result : "00012345_32423_131.xyz"
EDIT :
the fast, no-splitting but no-regex, solution I gave in comments :
"00000000".slice(Math.min(input.indexOf('_'), input.indexOf('.'))+1)+input
I wouldn't split at all, just replace:
"123456_r.xyz\n12345_32423_131.xyz\n1235.xyz\n237213_21_mmm.xyz".replace(/^[0-9]+/mg, function(a) {return '00000000'.slice(0, 8-a.length)+a})
There's a simple regexp to find the part of the string you want to replace, but you'll need to use a replace function to perform the action you want.
// The array with your strings
var strings = [
'123456_r.xyz',
'12345_32423_131.xyz',
'1235.xyz',
'237213_21_mmm.xyz'
];
// A function that takes a string and a desired length
function addLeadingZeros(string, desiredLength){
// ...and, while the length of the string is less than desired..
while(string.length < desiredLength){
// ...replaces is it with '0' plus itself
string = '0' + string;
}
// And returns that string
return string;
}
// So for each items in 'strings'...
for(var i = 0; i < strings.length; ++i){
// ...replace any instance of the regex (1 or more (+) integers (\d) at the start (^))...
strings[i] = strings[i].replace(/^\d+/, function replace(capturedIntegers){
// ...with the function defined above, specifying 8 as our desired length.
return addLeadingZeros(capturedIntegers, 8);
});
};
// Output to screen!
document.write(JSON.toString(strings));

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.

Using JS Regex to obtain the first value proceeding a string with dynamic trailing values

Given the following string variations:
var string = "groups/Da12312a"
var string = "groups/Da12312a/search"
var string = "groups/Da12312a/search/sam"
var string = "groups/3131"
var string = "groups/444/search"
var string = "groups/123asdadsZad/search/sam"
How can I get back just the value following groups/ and ending at the first '/'?
desired output:
Da12312a
Da12312a
Da12312a
3131
444
123asdadsZad
Using jQuery or JavaScript? Thanks
You can use the split method.
string.split("/")[1];
I would use a simple regular expression.
var str = 'groups/foo';
var matches = /groups\/([^/]*)/.exec(str);
matches will now contain an array where index 0 is "groups/100" and index 1 is "foo".
["groups/foo", "foo"]
If you want a regex, you can use the following:
/^[^\/]*?\/([^\/]*).*/
Basically the captured group yields your desired result.
Use like:
"groups/Da12312a/search".match(/^[^\/]*?\/([^\/]*).*/)
["groups/Da12312a/search", "Da12312a"]
"groups/Da12312a".match(/^[^\/]*?\/([^\/]*).*/)
["groups/Da12312a", "Da12312a"]
"groups/3131".match(/^[^\/]*?\/([^\/]*).*/)
["groups/3131", "3131"]
As you can see, in each of the cases the array index [1] is your result.
Hope that helps.
var output = string.split('/')[1];
String.split reference.
Here's a demo with your provided examples and output.

Categories

Resources