I have a dynamically formed string like - part1.abc.part2.abc.part3.abc
In this string I want to get the substring based on second to last occurrence of "." so that I can get and part3.abc
Is there any direct method available to get this?
You could use:
'part1.abc.part2.abc.part3.abc'.split('.').splice(-2).join('.'); // 'part3.abc'
You don't need jQuery for this.
Nothing to do with jQuery. You can use a regular expression:
var re = /[^\.]+\.[^\.]+$/;
var match = s.match(re);
if (match) {
alert(match[0]);
}
or
'part1.abc.part2.abc.part3.abc'.match(/[^.]+\.[^.]+$/)[0];
but the first is more robust.
You could also use split and get the last two elements from the resulting array (if they exist).
Related
I have the following text string:
test-shirt-print
I want to filter the text string so that it only returns me:
test-shirt
Meaning that everything that comes after the second hyphen should be removed including the hyphen.
I am thinking that the solution could be to split on hyphen and somehow select the two first values, and combine them again.
I am unaware of which functionality is best practice to use here, I also thinking that if it would be possible to use a regular expression in order to be able to select everything before the second hyphen.
You can use split slice and join together to remove everything after the second hyphen
var str = "test-shirt-print";
console.log(str.split("-").slice(0, 2).join('-'))
You can try with String.prototype.slice()
The slice() method extracts a section of a string and returns it as a new string, without modifying the original string.
and String.prototype.lastIndexOf()
The lastIndexOf() method returns the index within the calling String object of the last occurrence of the specified value, searching backwards from fromIndex. Returns -1 if the value is not found.
var str = 'test-shirt-print';
var res = str.slice(0, str.lastIndexOf('-'));
console.log(res);
You can also use split() to take the first two items and join them:
var str = 'test-shirt-print';
var res = str.split('-').slice(0,2).join('-');
console.log(res);
I have a Javascript array of string that contains urls like:
http://www.example.com.tr/?first=DSPN47ZTE1BGMR&second=NECEFT8RYD
http://www.example.com.tr/?first=RTR22414242144&second=YUUSADASFF
http://www.example.com.tr/?first=KOSDFASEWQESAS&second=VERERQWWFA
http://www.example.com.tr/?first=POLUJYUSD41234&second=13F241DASD
http://www.example.com.tr/?first=54SADFD14242RD&second=TYY42412DD
I want to extract "first" query parameter values from these url.
I mean i need values DSPN47ZTE1BGMR, RTR22414242144, KOSDFASEWQESAS, POLUJYUSD41234, 54SADFD14242RD
Because i am not good using regex, i couldnt find a way to extract these values from the array. Any help will be appreciated
Instead of using regex, why not just create a URL object out of the string and extract the parameters natively?
let url = new URL("http://www.example.com.tr/?first=54SADFD14242RD&second=TYY42412DD");
console.log(url.searchParams.get("first")); // -> "54SADFD14242RD"
If you don't know the name of the first parameter, you can still manually search the query string using the URL constructor.
let url = new URL("http://www.example.com.tr/?first=54SADFD14242RD&second=TYY42412DD");
console.log(url.search.match(/\?([^&$]+)/)[1]); // -> "54SADFD14242RD"
The index of the search represents the parameter's position (with index zero being the whole matched string). Note that .match returns null for no matches, so the code above would throw an error if there's no parameters in the URL.
Does it have to use regex? Would something like the following work:
var x = 'http://www.example.com.tr/?first=DSPN47ZTE1BGMR&second=NECEFT8RYD';
x.split('?first=')[1].split('&second')[0];
Try this regex:
first=([^&]*)
Capture the contents of Group 1
Click for Demo
Code
Explanation:
first= - matches first=
([^&]*) - matches 0+ occurences of any character that is not a & and stores it in Group 1
You can use
(?<=\?first=)[^&]+?
(?<=\?first=) - positive look behind to match ?first=
[^&]+? - Matches any character up to & (lazy mode)
Demo
Without positive look behind you do like this
let str = `http://www.example.com.tr/?first=DSPN47ZTE1BGMR&second=NECEFT8RYD
http://www.example.com.tr/?first=RTR22414242144&second=YUUSADASFF
http://www.example.com.tr/?first=KOSDFASEWQESAS&second=VERERQWWFA
http://www.example.com.tr/?first=POLUJYUSD41234&second=13F241DASD
http://www.example.com.tr/?first=54SADFD14242RD&second=TYY42412DD`
let op = str.match(/\?first=([^&]+)/g).map(e=> e.split('=')[1])
console.log(op)
I have a stringified JSON which looks like this:
...
"message":null,"elementId:["xyz1","l9ie","xyz1"]}}]}], "startIndex":"1",
"transitionTime":"3","sourceId":"xyz1","isLocked":false,"autoplay":false
,"mutevideo":false,"loopvideo":false,"soundonhover":false,"videoCntrlVisibility":0,
...,"elementId:["dgff","xyz1","jkh90"]}}]}]
... it goes on.
The part I need to work on is the value of the elementId key. (The 2nd key in the first line, and the last key).
This key is present in multiple places in the JSON string. The value of this key is an array containing 4-character ids.
I need to replace one of these ids with a new one.
The kernel of the idea is something like:
var elemId = 'xyz1' // for instance
var regex = new RegExp(elemId, 'g');
var newString = jsonString.replace(regex, newRandomId);
jsonString = newString;
There are a couple of problems with this approach. The regex will match the id anywhere in the JSON. I need a regex which only matches it inside the elementId array; and nowhere else.
I'm trying to use a capturing group to match just the occurrences I need, but I can't quite crack it. I have:
/.*elementId":\[".*(xyz1).*"\]}}]/
But this doesn't match the 1st occurence of 'xyz1 in the array.
So, firstly, I need a regex which can match all the 'xyz1's inside elementId; but nowhere else. The sequence of square and curly brackets after elementId ends doesn't change anywhere in the string, if that helps.
Secondly, even if I have a capturing group that works, string.replace doesn't act as expected. Instead of replacing just the match inside the capturing group, it replaces the whole match.
So, my second requirement is replacing only the captured groups, not the whole match.
What a need is a piece of js code which will replace my 'xyz1's where needed and return the following string (assuming the newRandomId is 'abcd'):
"message":null,"elementId:["abcd","l9ie","abcd"]}}]}], "startIndex":"1",
"transitionTime":"3","sourceId":"xyz1","isLocked":false,"autoplay":false
,"mutevideo":false,"loopvideo":false,"soundonhover":false,"videoCntrlVisibility":0,
...,"elementId:["dgff","abcd","jkh9"]}}]}]
Note that the value of 'sourceId' is unaffected.
EDIT: I have to work with the JSON. I can't parse it and work with the object since I don't know all the places the old id might be in the object and looping through it multiple times (for multiple elements) would be time-consuming
Assuming you can't just parse and change the JS object, you could use 2 regexes: one to extract the array and the one to change the desired ids inside:
var output = input.replace(/("elementId"\s*:\s*\[)((?:".{4}",?)*)(\])/g, function(_,start,content,end){
return start + content.replace(/"xyz1"/g, '"rand"') + end;
});
The arguments _, start, content, end are produced as result of the regex (documentation here):
_ is the whole matched string (from "elementId:\[ to ]). I choose this name because it's an old convention for arguments you don't use
start is the first group ("elementId:\[)
content is the second captured group, that is the internal part of the array
end id the third group, ]
Using the groups instead of hardcoding the start and end parts in the returned string serves two purposes
avoid duplication (DRY principle)
make it possible to have variable strings (for example in my regex I accept optional spaces after the :)
var input = document.getElementById("input").innerHTML.trim();
var output = input.replace(/("elementId":\s*\[)((?:".{4}",?)*)(\])/g, function(_,start,content,end){
return start + content.replace(/"xyz1"/g, '"rand"') + end;
});
document.getElementById("output").innerHTML = output;
Input:
<pre id=input>
"message":null,"elementId":["xyz1","l9ie","xyz1"]}}]}], "startIndex":"1",
"transitionTime":"3","sourceId":"xyz1","isLocked":false,"autoplay":false
,"mutevideo":false,"loopvideo":false,"soundonhover":false,"videoCntrlVisibility":0,
...,"elementId":["dgff","xyz1","jkh9"]}}]}]
</pre>
Output:
<pre id=output>
</pre>
Notes:
it would be easy to do the whole operation in one regex if they weren't repetition of the searched id in one array. But the present structure makes it easy to handle several ids to replace at once.
I use non captured groups (?:...) in order to unclutter the arguments passed to the external replacing callback
Basically, I'm trying to replace parts of a string using elements from an associative array. However, I need to grab elements based on backreferences generated from capturing groups in a replace() expression.
Using the first capturing group, I created this code, which doesn't work:
content = content.replace(/%(\w+)%/g,this.vars["$1"]);
(The regex works fine... I just can't get it to grab the array element.)
How would I go about implementing something like this?
String.replace can take a function as the second argument.
var that = this,
re = /%(\w+)%/g;
content = content.replace(re, function (str, p1)
{
return that.vars[p1];
});
I'm trying to find all occurrences of items in HTML page that are in between <nobr> and </nobr> tags.
EDIT:(nobr is an example. I need to find content between random strings, not always tags)
I tried this
var match = /<nobr>(.*?)<\/nobr>/img.exec(document.documentElement.innerHTML);
alert (match);
But it gives only one occurrence. + it appears twice, once with the <nobr></nobr> tags and once without them. I need only the version without the tags.
you need to do it in a loop
var match, re = /<nobr>(.*?)<\/nobr>/img;
while((match = re.exec(document.documentElement.innerHTML)) !== null){
alert(match[1]);
}
use the DOM
var nobrs = document.getElementsByTagName("nobr")
and you can then loop through all nobrs and extract the innerHTML or apply any other action on them.
(Since I can't comment on Rafael's correct answer...)
exec is doing what it is supposed to do - finding the first match, returning the result in the match object, and setting you up for the next exec call. The match object contains (at index 0) the whole of the string matched by the whole of the regex. In subsequent slots are the bits of the string matched by the parenthesized subgroups. So match[1] contains the bit of the string matched by "(.*?)" in your example.
you can use
while (match = /<nobr>(.*?)<\/nobr>/img.exec("foo <nobr> hello </nobr> bar <nobr> world </nobr> foobar"))
alert (match[1]);
If the strings you're using aren't xml elements, and you're sticking with regexes the return value you're getting can be explained by the bracketing. .exec returns the whole matching string followed by the contents of the bracketed expressions.
If your doc contains:
This is out.
Bzz. This is in. unBzz.
then
/Bzz.(.*?)unBzz./img.exec(document.documentElement.innerHTML)
Will give you 'Bzz. This is in. unBzz.' in element 0 of the returned array and 'This is in.' in element 1. Trying to display the whole array gives both as a comma separated list because that's what JavaScript does to try to display it.
So
alert($match[1]);
is what you're after.
it takes to steps but you could do it like this
match = document.documentElement.innerHTML.match(/<nobr>(.*?)<\/nobr>/img)
alert(match)//includes '<nobr>'
match_length = match.length;
for (var i = 0; i < match_length; i++)
{
var match2 = match[i].match(/<nobr>(.*?)<\/nobr>/im);//same regex without the g option
alert(match2[1]);
}