JavaScript - Regex: URL has a param - javascript

I'm trying to create an analog for php's isset ($_GET[param]) but for JavaScript.
So long, I get this
[?&]param[&=]
But if param is at the end of URL (example.com?param) this regex won't work.
You can play with it here: https://regex101.com/r/fFeWPW/1

If you want to make sure your match ends with &, = or end of string, you may replace the [&=] character class with a (?:[&=]|$) alternation group that will match &, = or end of string (note that $ cannot be placed inside the character class as it would lose its special meaning there and will be treated as a $ symbol), or you may use a negative lookahead (?![^&=]) that fails the match if there is no & or = immediately after the current location, which might be a bit more efficient than an alternation group.
So, in your case, it will look like
[?&]param(?:[&=]|$)
or
[?&]param(?![^&=])
See a regex demo
JS demo:
var strs = ['http://example.com?param', 'http://example.com?param=123', 'http://example.com?param&another','http://example.com?params'];
var rx = /[?&]param(?![^&=])/;
for (var s of strs) {
console.log(s, "=>", rx.test(s))
}

Related

how to found 2 matches in regular expression

I need a regular expression for :
<<12.txt>> <<45.txt>
I have created a regular expression :
<<.+.txt>>
But this found one match in whole string but here is 2 matches:
<<12.txt>>
<<45.txt>>
if anyone have solution for this problem please help me out there
Part of the issue is that the string you've specified wouldn't match because the second > is missing in <<45.txt>.
Also, you're using the . (dot) selector, and also trying to find a period. It works, but now how you think it is.
Here's the regex you want:
var regex = /<<\d+\.txt>>/g
\d matches only numbers
\. matches an actual period
/g means global, so it won't stop at the first match
Practice Regular Expressions
https://regexr.com/43bs4
Demo
var string = "<<12.txt>> <<45.txt>>";
var regex = /<<\d+\.txt>>/g;
var matches = string.match(regex);
console.log(matches);
P.S., if you actually want to match with 1 > or 2 >>, you can with:
var regex = /<<\d+\.txt>>?/g
? optionally matches the character right before it
/<<.+.txt>>/gm
g is for global (will search through entire source)
m is for multi line search support

Remove hashtag symbol js, by regex

Tried to search on the forum but could not find anything that would precisely similar to what i need. Im basically trying to remove the # symbol from results that im receving, here is the dummy example of the regex.
let postText = 'this is a #test of #hashtags';
var regexp = new RegExp('#([^\\s])', 'g');
postText = postText.replace(regexp, '');
console.log(postText);
It gives the following result
this is a est of ashtags
What do i need to change around so that it removes just the hashtags without cutting the first letter of each word
You need a backreference $1 as the replacement:
let postText = 'this is a #test of #hashtags';
var regexp = /#(\S)/g;
postText = postText.replace(regexp, '$1');
console.log(postText);
// Alternative with a lookahead:
console.log('this is a #test of #hashtags'.replace(/#(?=\S)/g, ''));
Note I suggest replacing the constructor notation with a regex literal notation to make the regex a bit more readable, and changing [^\s] with a shorter \S (any non-whitespace char).
Here, /#(\S)/g matches multiple occurrences (due to g modifier) of # and any non-whitespace char right after it (while capturing it into Group 1) and String#replace will replace the found match with that latter char.
Alternatively, to avoid using backreferences (also called placeholders) you may use a lookahead, as in .replace(/#(?=\S)/g, ''), where (?=\S) requires a non-whitespace char immediately to the right of the current location. If you need to remove # at the end of the string, too, replace (?=\S) with (?!\s) that will fail the match if the next char is a whitespace.
Probably easier will be to write your own function which probably will look like this: (covers the usecase when symbol may be repeated)
function replaceSymbol(symbol, string) {
if (string.indexOf(symbol) < 0) {
return string;
}
while(string.indexOf(symbol) > -1) {
string = string.replace(symbol, '');
}
return string;
}
var a = replaceSymbol('#', '##s##u#c###c#e###ss is he#re'); // 'success is here'
You might be able to use the following :
let postText = 'this is a #test of #hashtags';
postText = postText.replace(/#\b/g, '');
It relies on the fact that a #hashtag contains a word-boundary between the # and the word that follows it. By matching that word-boundary with \b, we make sure not to match single #.
However, it might match a bit more than you would expect, because the definition of 'word character' in regex isn't obvious : it includes numbers (so #123 would be matched) and more confusingly, the _ character (so #___ would be matched).
I don't know if there's an authoritative source defining whether those are acceptable hashtags or not, so I'll let you judge whether this suits your needs.
You only need the #, the stuff in parens match anything else after said #
postText = postText.replace('#', '');
This will replace all #

Javascript: Remove trailing chars from string if they are non-numeric

I am passing codes to an API. These codes are alphanumeric, like this one: M84.534D
I just found out that the API does not use the trailing letters. In other words, the API is expecting M84.534, no letter D at the end.
The problem I am having is that the format is not the same for the codes.
I may have M84.534DAC, or M84.534.
What I need to accomplish before sending the code is to remove any non-numeric characters from the end of the code, so in the examples:
M84.534D -> I need to pass M84.534
M84.534DAC -> I also need to pass M84.534
Is there any function or regex that will do that?
Thank you in advance to all.
You can use the regex below. It will remove anything from the end of the string that is not a number
let code = 'M84.534DAC'
console.log(code.replace(/[^0-9]+?$/, ""));
[^0-9] matches anything that is not a numer
+? Will match between 1 and unlimited times
$ Will match the end of the string
So linked together, it will match any non numbers at the end of the string, and replace them with nothing.
You could use the following expression:
\D*$
As in:
var somestring = "M84.534D".replace(/\D*$/, '');
console.log(somestring);
Explanation:
\D stands for not \d, the star * means zero or more times (greedily) and the $ anchors the expression to the end of the string.
Given your limited data sample, this simple regular expression does the trick. You just replace the match with an empty string.
I've used document.write just so we can see the results. You use this whatever way you want.
var testData = [
'M84.534D',
'M84.534DAC'
]
regex = /\D+$/
testData.forEach((item) => {
var cleanValue = item.replace(regex, '')
document.write(cleanValue + '<br>')
})
RegEx breakdown:
\D = Anything that's not a digit
+ = One or more occurrences
$ = End of line/input

match a string not after another string

This
var re = /[^<a]b/;
var str = "<a>b";
console.log(str.match(re)[0]);
matches >b.
However, I don't understand why this pattern /[^<a>]b/ doesn't match anything. I want to capture only the "b".
The reason why /[^<a>]b/ doesn't do anything is that you are ignoring <, a, and > as individual characters, so rewriting it as /[^><a]b/ would do the same thing. I doubt this is what you want, though. Try the following:
var re = /<a>(b)/;
var str = "<a>b";
console.log(str.match(re)[1]);
This regex looks for a string that looks like <a>b first, but it captures the b with the parentheses. To access the b, simply use [1] when you call .match instead of [0], which would return the entire string (<a>b).
What you're using here is a match for a b preceded by any character that is not listed in the group. The syntax [^a-z+-] where the a-z+- is a range of characters (in this case, the range of the lowercase Latin letters, a plus sign and a minus sign). So, what your regex pattern matches is any b preceded by a character that is NOT < or a. Since > doesn't fall in that range, it matches it.
The range selector basically works the same as a list of characters that are seperated by OR pipes: [abcd] matches the same as (a|b|c|d). Range selectors just have an extra functionality of also matching that same string via [a-d], using a dash in between character ranges. Putting a ^ at the start of a range automatically turns this positive range selector into a negative one, so it will match anything BUT the characters in that range.
What you are looking for is a negative lookahead. Those can exclude something from matching longer strings. Those work in this format: (?!do not match) where do not match uses the normal regex syntax. In this case, you want to test if the preceding string does not match <a>, so just use:
(?!<a>)(.{3}|^.{0,2})b
That will match the b when it is either preceded by three characters that are not <a>, or by fewer characters that are at the start of the line.
PS: what you are probably looking for is the "negative lookbehind", which sadly isn't available in JavaScript regular expressions. The way that would work is (?<!<a>)b in other languages. Because JavaScript doesn't have negative lookbehinds, you'll have to use this alternative regex.
you could write a pattern to match anchor tag and then replace it with empty string
var str = "<a>b</a>";
str = str.replace(/((<a[\w\s=\[\]\'\"\-]*>)|</a>)/gi,'')
this will replace the following strings with 'b'
<a>b</a>
<a class='link-l3'>b</a>
to better get familiar with regEx patterns you may find this website very useful regExPal
Your code :
var re = /[^<a>]b/;
var str = "<a>b";
console.log(str.match(re));
Why [^<a>]b is not matching with anything ?
The meaning of [^<a>]b is any character except < or a or > then b .
Hear b is followed by > , so it will not match .
If you want to match b , then you need to give like this :
var re = /(?:[\<a\>])(b)/;
var str = "<a>b";
console.log(str.match(re)[1]);
DEMO And EXPLANATION

Regex to find last token on a string

I was wondering if there is a way having this
var string = "foo::bar"
To get the last part of the string: "bar" using just regex.
I was trying to do look-aheads but couldn't master them enough to do this.
--
UPDATE
Perhaps some examples will make the question clearer.
var st1 = "foo::bar::0"
match should be 0
var st2 = "foo::bar::0-3aab"
match should be 0-3aab
var st3 = "foo"
no match should be found
You can use a negative lookahead:
/::(?!.*::)(.*)$/
The result will then be in the capture.
Another approach:
/^.*::(.*)$/
This should work because the .* matches greedily, so the :: will match the last occurence of that string.
Simply,
/::(.+)$/
You can't use lookaheads unless you know exactly how long a string you're trying to match. Fortunately, this isn't an issue, because you're only looking at the end of the string $.
I wouldn't use regular expressions for this (although you certainly can); I'd split the string on ::, since that's conceptually what you want to do.
function lastToken(str) {
var xs = str.split('::');
return xs.length > 1 ? xs.pop() : null;
}
If you really want just a regular expression, you can use /::((?:[^:]|:(?!:))*)$/. First, it matches a literal ::. Then, we use parentheses to put the desired thing in capturing group 1. The desired thing is one or more copies of a (?:...)-bracketed string; this bracketing groups without capturing. We then look for either [^:], a non-colon character, or :(?!:), a colon followed by a non-colon. The (?!...) is a negative lookahead, which matches only if the next token doesn't match the contained pattern. Since JavaScript doesn't support negative lookbehinds, I can't see a good way to avoid capturing the :: as well, but you can wrap this in a function:
function lastTokenRegex(str) {
var m = str.match(/::((?:[^:]|:(?!:))*)$/);
return m && m[1];
}
var string2 = string.replace(/.*::/, "");
though perhaps string isn't the best choice of name for your string?

Categories

Resources