RegEx is not working with backslash in javascript [duplicate] - javascript

This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 7 years ago.
I am trying to validate strings with following pattern.
starts with 3 digits followed by hyphen followed by 2 digits and ends with 4 digits.
eg : 123-45-6789
I need to pass the pattern to a RegExp object as a string variable (I am getting the pattern value from a html element attribute ), hence I have escaped the RegExp with double slashes. To my surprise, I am seeing weird results.
var pattern = "^\\d{3}-\\d{2}-\\d{4}$";
var inputRegex = new RegExp(pattern, "g");
console.log(inputRegex.test('132-45-7899')); //True
console.log(inputRegex.test('132-45-7899')); //False
console.log(inputRegex.test('132-45-7899')); //True
console.log(inputRegex.test('132-45-7899')); //False
What am I doing wrong here? and what is the reason for this inconsistent results?
EDIT:
Now I understood why the results are inconsistent , but my actual problem remained unsolved.
HTML elem is like below
SCENARIO 1:
<input data-val-regexp="^\\d{3}-\\d{2}-\\d{4}$" id="ticketNumber">
var regexPattern = input.attr("data-val-regexp");
var inputRegex = new RegExp(regexPattern);
return inputRegex.test('123-45-6789'); // False
When I inspected, the inputRegex.source is "^\\d{3}-\\d{2}-\\d{4}$"
SCENARIO 2:
If I assign the regexPattern with string literals everything works fine.
var pattern = "^\\d{3}-\\d{2}-\\d{4}$";
var inputRegex = new RegExp(pattern);
console.log(inputRegex.test('132-45-7899')); //True
In the above case inputRegex source value is "^\d{3}-\d{2}-\d{4}$"
Why is the backslash escaped in the second scenario, where as it didn't in the first scenario? What needs to be done in order to make scenario 1 work?

Because you're creating the regular expression with the g flag, it remembers where it left off and starts matching there, instead of at the beginning, the next time you call test. See Why does Javascript's regex.exec() not always return the same value?.

Related

Replacing only exact matches in Regex [duplicate]

This question already has answers here:
How can I match a whole word in JavaScript?
(4 answers)
Closed 4 months ago.
I have a javascript function that replaces strings that match against a profanity library with symbols.
eg. damn is transformed into ##$%&!
However, this replace is non-discriminating, and will transform partial matches as well.
eg. classic is transformed into cl##$%&!ic
I'm very new to TS/JS and Regex and would like some help understanding this function's arguments and how to modify them for only exact matches.
this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, "\\$&"), (ignore ? "gi" : "g")), (typeof (str2) == "string") ? str2.replace(/\$/g, "$$$$") : str2);
To avoid partial matches, the normal solution is to surround what you want to match with word boundaries \b.
The following example assumes that profanities does not contain any words that contain regex special characters.
Notice that the "shit" in "mishit" and the "ass" in "class" do not get replaced.
const profanities = ['damn', 'shit', 'ass'];
// As regex literal: /\b(?:damn|shit|ass)\b/
const re = new RegExp('\\b(?:' + profanities.join('|') + ')\\b', 'gi');
const text = "Damn, another mishit. I am shit at pool. Time to get my ass to class.";
console.log(text.replace(re, '##$%&!'));

RegExp vs /.../ [duplicate]

This question already has answers here:
JavaScript: RegExp constructor vs RegEx literal
(4 answers)
Closed 4 years ago.
I am trying to learn regular expressions in Javascript through this brilliant book "Eloquent Javascript" by Marijn Haverbeke. I am unable to figure out why some of these match and why some don't even though they seem fine. I don't know if I have misunderstood something or understood something partially. For example -
console.log(/'\d+'/.test("123"));
// This doesn't match
console.log(/'\d+'/.test("'123'"));
// This matches
let myRegEx = new RegExp("\d+");
console.log(myRegEx.test("123"));
//Doesn't match
console.log(myRegEx.test("'123'"));
//Doesn't match either
Also, why are '' required inside "" for the string to be matched?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
The correct code:
console.log(/\d+/.test("123"));
or
let myRegEx = new RegExp("\\d+");
console.log(myRegEx.test("123"));
You have to add \ for the new RegExpr because "\\d+" is a string interpreted as "\d+"
Also, why are '' required inside "" for the string to be matched?
They are not:
/\d+/ matches "A number, one or more that one time"
/'\d+'/ matches "A quote, then A number, one or more that one time, then a quote"
So:
/\d+/.test("123") === true
/'\d+'/.test("123") === false (because ' are not found)
/\d+/.test("'123'") === true (because numbers are found)
/'\d+'/.test("'123'") === true
\ is an escape character in string literals as well as regular expressions.
"\d+" is the same as "d+" so you are testing for 1 or more instances of the character d.

simple regular expression with equals but dont want to use split [duplicate]

This question already has answers here:
Regular Expressions in JavaScript for URL Capture
(4 answers)
Closed 7 years ago.
I have the message string as follows.
string=052
I need to use regular expression not split.
I want to return everything past the equals. 052
This is what i tried and gives me id=null
var regex = '[^?string=]';
var id2 = mystring.match(regex);
I have tried online regex checkers and it looks like it matches all but the a
is there a better reg ex i should try? id should not equal null.
You're using String.match() incorrectly. Try this:
var regex = '^message=(.*)$';
var id = queryString.match(regex)[1];
.match() returns an array; the first element (at [0]) is the entire matched string, and the second element (at [1]) is the part that's matched in the (first) set of parentheses in the regex.

Why `pattern.test(name)` opposite results on consecutive calls [duplicate]

This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 7 years ago.
Why is this code returning first true, then false
var pattern = new RegExp("mstea", 'gi'), name = "Amanda Olmstead";
console.log('1', pattern.test(name));
console.log('1', pattern.test(name));
Demo: Fiddle
g is for repeating searches. It changes the regular expression object into an iterator. If you want to use the test function to check your string is valid according to your pattern, remove this modifier :
var pattern = new RegExp("mstea", 'i'), name = "Amanda Olmstead";
The test function, contrary to replace or match doesn't consume the whole iteration, which lets it in a "bad" state. You should probably never use this modifier when using the test function.
You don't want to use gi in combination with pattern.test. The g flag means that it keeps track of where you are running so it can be reused. So instead, you should use:
var pattern = new RegExp("mstea", 'i'), name = "Amanda Olmstead";
console.log('1', pattern.test(name));
console.log('1', pattern.test(name));
Also, you can use /.../[flags] syntax for regex, like so:
var pattern = /mstea/i;
Because you set the g modifier.
Remove it for your case.
var pattern = new RegExp("mstea", 'i'), name = "Amanda Olmstead";
It isn't a bug.
The g causes it to carry out the next attempted match for the substring, after the first match. And that is why it returns false in every even attempt.
First attempt:
It is testing "Amanda Olmstead"
Second attempt:
It is testing "d" //match found in previous attempt (performs substring there)
Third attempt:
It is testing "Amanda Olmstead" again //no match found in previous attempt
... so on
MDN page for Regexp.exec states:
If your regular expression uses the "g" flag, you can use the exec
method multiple times to find successive matches in the same string.
When you do so, the search starts at the substring of str specified by
the regular expression's lastIndex property
MDN page for test states:
As with exec (or in combination with it), test called multiple times
on the same global regular expression instance will advance past the
previous match.

passing variable to a regexp in javascript [duplicate]

This question already has answers here:
How do you use a variable in a regular expression?
(27 answers)
Is there a RegExp.escape function in JavaScript?
(18 answers)
Closed 4 years ago.
Possible Duplicate:
Escape string for use in Javascript regex
I have a msg like this:
Max {0} chars allowed in {1}
And I have a function to create a message using the arguments passed as
for(var i = 0; i < agrs.length; i++){
reg = new RegExp('\{'+i+'\}', 'gi');
key = key.replace(reg,agrs[i])
}
The problem is that it's not able to take the param i to create the reg exp.
What's the way to achieve this?
Your regexp is /{0}/gi since you create it from a string. And it is not a valid expression.
You need to escape { in the regexp because it has a special meaning in the regexp syntax, so it should be:
new RegExp('\\{'+i+'\\}', 'gi');
which is /\\{0\\}/gi. You need to escape the escaping \\ in the string.
I would strongly encourage you to use the functional form of String.replace() to solve your problem, rather than trying to parametrize the regexp in a for-loop that iterates over {0},{1},etc.
In other words, rather than look for '{0}' or '{1}', just look for '{([0-9]+)}' (i.e. {}'s surrounding an arbitrary number, and pass a function to the replace() function to intelligently replace these expressions based on the number between the {}'s. This lets you use a RegExp literal which you can write as /{([0-9]+)}/ rather than mess around with escape characters in strings.
Something like this:
s='the song says {0} little {1} little {2} little-endians';
args=['zero','one','two'];
new_string = s.replace(/{([0-9]+)}/g, function(wholematch,firstmatch)
{return args[(+firstmatch)]; }
);
which yields
the song says zero little one little two little-endians
See this similar question.
edit: if you want to leave alone items that are greater than the length of your args list, make sure to sanity-check the parameter number:
s='the song says {0} little {1} little {2} little-endians,\n'+
' {3} little {4} little {5} little-endians';
args=['zero','one','two'];
new_string = s.replace(/{([0-9]+)}/g, function(wholematch,firstmatch)
{var i = +firstmatch; return i < args.length ? args[i] : wholematch;}
);
which yields
the song says zero little one little two little-endians,
{3} little {4} little {5} little-endians
I think your second line is supposed to be
reg = new RegExp('\{'+i+'\}', 'gi');
but I don't know if that's your only problem or not.
function escapeRegExp(str) {
return str.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
var re = new RegExp(escapeRegExp(str));
See: Escape string for use in Javascript regex

Categories

Resources