There is a data parameter for a div that looks as follows:
<div data-params="[possibleText&]start=2011-11-01&end=2011-11-30[&possibleText]">
</div>
I want to remove the from the start through the end of the second date from that data-params attribute. There may or may not be text before the start and after the date after the second date.
How can I accomplish this using javascript or jQuery? I know how to get the value of the "data-params" attribute and how to set it, I'm just not sure how to remove just that part from the string.
Thank you!
Note: The dates will not always be the same.
I'd use a regular expression:
var text = $('div').attr('data-params');
var dates = text.match(/start=\d{4}-\d{2}-\d{2}&end=\d{4}-\d{2}-\d{2}/)[0]
// dates => "start=2011-11-01&end=2011-11-30"
The regular expression is not too complex. The notation \d means "match any digit" and \d{4} means "match exactly 4 digits". The rest is literal characters. So you can see how it works. Finally, that [0] at the end is because javascript match returns an array where the first element is the whole match and the rest are subgroups. We don't have any subgroups and we do want the whole match, so we just grab the first element, hence [0].
If you wanted to pull out the actual dates instead of the full query string, you can create subgroups to match by adding parenthesis around the parts you want, like this:
var dates = text.match(/start=(\d{4}-\d{2}-\d{2})&end=(\d{4}-\d{2}-\d{2})/)
// dates[0] => "start=2011-11-01&end=2011-11-30"
// dates[1] => "2011-11-01"
// dates[2] => "2011-11-30"
Here, dates[1] is the start date (the first subgroup based on parenthesis) and dates[2] is the end date (the second subgroup).
My regex skills aren't that good but this should do it
var txt = "[possibleText&]start=2011-11-01&end=2011-11-30[&possibleText]";
var requiredTxt = txt.replace(/^(.*)start=\d{4}-\d{2}-\d{2}&end=\d{4}-\d{2}-\d{2}(.*)$/, "$1$2");
I'm sure there are better ways to match your string with regex, but the $1 and $2 will put the first group and second group match into your requiredTxt stripping out the start/end stuff in the middle.
Say you have your data-params in a variable foo. Call foo.match as follows:
foo.match("[\\?&]start=([^&#]*)"); //returns ["&start=2011-11-01", "2011-11-01"]
foo.match("[\\?&]end=([^&#]*)"); //returns ["&end=2011-11-30", "2011-11-30"]
Related
I have troubles with a regular expression.
I want to replace all ocurrences of myData=xxxx& xxxx can change, but always ends with &, except the last ocurrence, when it is myData=xxx.
var data = "the text myData=data1& and &myData=otherData& and end myData=endofstring"
data.replace(/myData=.*?&/g,'newData');
it returns :
the text newData and &newData and end myData=endofstring
which is correct, but how can I detect the last one?
Two things:
You need to assign the result of replace somewhere, which you're not doing in your question's code
You can use an alternation (|) to match either & or end of string
So:
var data = "the text myData=data1& and &myData=otherData& and end myData=endofstring"
data = data.replace(/myData=.*?(?:&|$)/g,'newData');
// ^^^^^^^-- 1 ^^^^^^^-- 2
console.log(data);
Note the use of a non-capturing group ((?:...)), to limit the scope of the alternation.
What about :
data="myData=abc& and linked with something else";
data.replace(/myData=.*?&/g,'newData');
https://jsfiddle.net/ob8c2j9v/
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
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).
Ok so i'm executing the following line of code in javascript
RegExp('(http:\/\/t.co\/)[a-zA-Z0-9\-\.]{8}').exec(tcont);
where tcont is equal to some string like 'Test tweet to http://t.co/GXmaUyNL' (the content of a tweet obtained by jquery).
However it is returning, in the case above for example, 'http://t.co/GXmaUyNL,http://t.co/'.
This is frustracting because I want the url without the bit on the end - after and including the comma.
Any ideas why this is appearing? Thanks
First, get rid of the parens in the pattern - they're unnecessary:
RegExp('http:\/\/t.co\/[a-zA-Z0-9\-\.]{8}').exec(tcont);
Second, a regex match returns an array of matching groups - you want the first item in it (the entire match):
var match = RegExp('http:\/\/t.co\/[a-zA-Z0-9\-\.]{8}').exec(tcont);
if(match) {
var result = match[0];
}
The reason you had "a part on the end" is because your result is actually an array - the parens you had in the expression were resulting in an extra matching group (the portion they were around), which would be match[1].
Try this : RegExp('http:\/\/t\.co\/[a-zA-Z0-9\-\.]{8}').exec(tcont);
I have a RegExp:
/.?(NCAA|Division|I|Basketball|Champions,|1939-2011).?/gi
and some text "Champion"
somehow, this is coming back as a match, am I crazy?
0: "pio"
1: "i"
index: 4
input: "Champion"
length: 2
the loop is here:
// contruct the pattern, dynamically
var someText = "Champion";
var phrase = ".?(NCAA|Division|I|Basketball|Champions,|1939-2011).?";
var pat = new RegExp(phrase, "gi"); // <- ends up being
var result;
while( result = pat.exec(someText) ) {
// do stuff!
}
There has to be something wrong with my RegExp, right?
EDIT:
The .? thing was just a quick and dirty attempt to say that I'd like to match one of those words AND/OR one of those words with a single char on either side. ex:
\sNCAA\s
NCAA
NCAA\s
\sNCAA
GOAL:
I'm trying to do some simple hit highlighting based on some search words. I've got a function that gets all of the text nodes on a page, and I'd like to go through them all and highlight any matches to any of the terms in my phrase variable.
I think that I just need to rework how I am building my RegExp.
Well, first of all you're specifying case-insensitivity, and secondly, you are matching the letter I as one of your matchable string.
Champion would match pio and i, because they both match /.?I.?/gi
It however doesn't match /.?Champions,.?/gi because of the trailing comma.
Add start (^) and end ($) anchors to the regexp.
/^.?(NCAA|Division|I|Basketball|Champions,|1939-2011).?$/gi
Without the anchors, the regexp's match can start and end anywhere in the string, which is why
/.?(NCAA|Division|I|Basketball|Champions,|1939-2011).?/gi.exec('Champion')
can match pio and i: because it's actually matching around the (case-insensitive) I. If you leave the anchors off, but remove the ...|I|..., the regex won't match 'Champion':
> /.?(NCAA|Division|Basketball|Champions,|1939-2011).?/gi.exec('Champion')
null
Champion matches /.?I.?/i.
Your own output notes that it's matching the substring "pio".
Perhaps you meant to bound the expression to the start and end of the input, with ^ and $ respectively:
/^.?(NCAA|Division|I|Basketball|Champions,|1939-2011).?$/gi
I know you said to ignore the .?, but I can't: it's most likely wrong, and it's most likely going to continue to cause you problems. Explain why they're there and we can tell you how to do it properly. :)