I'm a bit confused about different regex formats.
The following methods are causing an error.
function validateDate(str) {
var expr = /^((((0?[1-9]|[12]\d|3[01])[\/](0?[13578]|1[02])[\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)[\/](0?[13456789]|1[012])[\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])[\/]0?2[\/]((1[6-9]|[2-9]\d)?\d{2}))|(29[\/]0?2[\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$/;
return validate(expr, str);
}
function validateTime(str) {
var expr = /^([0-1]?[0-9]|[2]?[0-3])\:([0-5][0-9])$/;
return validate(expr, str);
}
function validate(pattern, str) {
return str.match(pattern);
}
I've taken the following regex's from the web. I think the problem is regarding certain escape characters
What's wrong here?
Thanks : )
In the validateDate function you are assigning the regular expression object to the exp variable, but in the next line you are using the expr variable, which is undefined.
Edit:
What do you expect the functions to return? Right now they are returning an array of matches. If you want them to just return true or false, you might want to use the test method instead:
function validate(pattern, str) {
return pattern.test(str);
}
Related
This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 5 years ago.
I found this really strange behavior when defining a regex as a class property in ES6. I currently encountered this behavior working with typescript and angular, but I made a stripped version in my chrome console and it was the same.
class RegexTest {
constructor() {
this.expression = /[\*|\-|\_]/g;
}
testStringExpression(word) {
return this.expression.test(word);
}
}
const tester = new RegexTest();
const words = "*, *, *, kitten";
const reduced = words.split(',').reduce((acc, item, index) => {
if ( tester.testStringExpression(item) ) {
return acc;
} else {
return acc + item + index;
}
}, "");
console.log(reduced); // Should be " kitten3", instead I'm getting " *2 kitten3"
However, If I just test the regular expression as it is inside the reduce, the result is the expected:
const words = "*, *, *, kitten";
const reduced = words.split(',').reduce((acc, item, index) => {
if ( /[\*|\-|\_]/g.test(item) ) {
return acc;
} else {
return acc + item + index;
}
}, "");
console.log(reduced); // " kitten3"
What am I'm getting wrong here?
From the MDN reference:
If the regex has the global flag set, test() will advance the lastIndex of the regex. A subsequent use of test() will start the search at the substring of str specified by lastIndex (exec() will also advance the lastIndex property).
So repeatedly using .test() on the same regex object, will NOT start matching the regex from the start of the string you try to match. So the first time you try to match the string "*", it will return true, since it starts searching from the start of that string.
Since the expression is a property of the class, you reuse the same regex again, the second time starting from the end of the string you send it, instead of from the start. So by the time you try to match " *", you''l get false instead of true.
By putting the regular expression inline, you create a new regex object every time, and hence the lastIndex won't get updated.
The solution here is to use the match method of words to test the regex, instead of using the regex to test the word.
So if you replace
return this.expression.test(word);
by
return word.match( this.expression );
everything will work as you expect and you get the string " kitten3".
Edit: Or you could just rewrite the regex to not use the global flag at all.
function palindrome(str) {
//Clean up string
var re = '/[^a-z0-9]/gi';
str=str.toLowerCase();
str=str.replace(re, '');
console.log(str);
//Reverse string and check
var pstr = str.split('').reverse().join('');
if (pstr === str){
return true;
}
return false;
}
palindrome("__Eye");
I'm trying to test a palindrome statement. I'm using https://regex101.com/ to test my regEx statements using sample statements
The function above is an attempt to check if a string value is a palindrome, return true if it is, return false if its not
Palindromes are things like race car where its spelled the same forward and backward
My regex expression is '[^a-z0-9]/gi' which selects all punctuation marks, commas, and spaces in order to delete them using a replace prototype string method. On testing the regex expression it looks fine, see below
problem:
Can someone shed light on what I am doing wrong here? The problem I have is that I am console.log(str) and its not reflecting the correct output. e.g.
__eye input should result in eye output but is not
repl to test code here https://repl.it/JVCf/21
EDIT PROBLEM SOLVED:
Its var re = /[^a-z0-9]/gi; NOT var re = '/[^a-z0-9]/gi';
RegEx Pattern is NOT a string
From the MDN documentation:
There are 2 ways to create a RegExp object: a literal notation and a constructor. To indicate strings, the parameters to the literal notation do not use quotation marks while the parameters to the constructor function do use quotation marks. So the following expressions create the same regular expression:
/ab+c/i;
new RegExp('ab+c', 'i');
new RegExp(/ab+c/, 'i');
The different methods have their different pros and cons.
function palindrome(str) {
//Clean up string
var re = /[^a-z0-9]/g; // note RegEx pattern is not a string
str=str.toLowerCase();
str=str.replace(re, '');
console.log(str);
//Reverse string and check
var pstr = str.split('').reverse().join('');
if (pstr === str){
return true;
}
return false;
}
palindrome("__Eye");
function function1(format) {
var regexp = /[<>]/g;
//Here the parameters are matched string,
//the position and the original text
var str = format.replace(regexp,function(match,position,originalText){
return match;
});
return str;
}
function function2(format) {
var regexp = /:(\w+)/g;
//Here the parameters are matched string,
//something like stripped string, and the position
var str = format.replace(regexp,function(match,stripped,position){
return match;
});
return str;
}
console.log(function1('<hello>'));
console.log(function2(':url :method'));
I got the first function from #Professional JavaScript for Web Developers#, and the second function from #NodeJS in Action#.
You can see that the call back function for replace is not consistent. Why?
The callback in function2 could be written with a 4th argument to appear less confusing and more consistent with the first callback in your examples:
function function2(format) {
var regexp = /:(\w+)/g;
var str = format.replace(regexp,function(match,submatch,position,originalText){
return match;
});
return str;
}
Look at how the callback in replace can be defined: it accepts a number of arguments >= 3. The optional arguments are used only if your regex contains submatches, and they correspond to the nth parenthesized submatch string:
function(match, [p1, p2, ...], offset, string) { ... }
Whats sounds confusing, I guess, is that they are placed in the middle. Also note that the callback function will be invoked multiple times for each full match to be replaced, if the regular expression in the first parameter is global (which is true in your example).
I need to write a regular expression that will check that the strings matches the format 'ACT' followed by 6 digits eg. 'ACT123456'
Though it looks quite simple, none of my options work; the function always returns false.
I tried the following combinations:
Pure regexpression literals
var format = /^ACT\d{6}$/;
var format = /^ACT[0-9]{6}$/;
Or using RegExp object with double escaping (eg. \\d) and with single escaping (\d)
var format = new RegExp("^ACT\\d{6}$");
var format = new RegExp("^ACT[0-9]{6}$");
My function for testing is:
function testPattern(field, pattern) {
if (!pattern.test(field)) {
return false;}
else {
return true;
}}
var format = /^ACT\d{6}$/;
works fine but the string must be ACT123456 exactly with nothing preceding it or following it
eg 'ACT123456 ' fails
use
/ACT\d{6}/
to allow more tolerance or strip the whitespace from the string first
var testString = "ACT123456"; // string to test
// pattern as a regex literal
var pattern = /^ACT[0-9]{6}$/g;
console.log(testString.match(pattern)); // output: ["ACT123456"]
Thanks you all guys for answers and feedback!
After being stuck with regular expressions, I realized that my problem with that I am not using field.value in my function.
So, the problem is with the function that must be:
function testPattern(field, pattern) {
if (!pattern.test(field.value)) {
return false;}
else {
return true;
}}
Need some help from you javascript regexp pro's
I have a function that I want to pass in some a "value" and a list of accepted characters. This function works in php, but the javascript variables don't work the same as in php, so I need some guiadance.
I would like to call this function like this:
isAlphaNumeric(myValue, "_-");
This would allow any number, or letter as well as the underscore and the hyphen, but no other characters
This is the function I have, but doesn't quite work right.
function isAlphaNumeric(value, allow)
{
var result = /^[A-Za-z0-9+allow+]+$/.test(value);
return result;
}
How can I accomplish what I'm after?
Thanks for the help.
Use RegExp object constructor
function isAlphaNumeric(value, allow)
{
var re = new RegExp( '^[A-Za-z0-9'+allow+']+$');
var result = re.test(value);
return result;
}
or
function isAlphaNumeric(value, allow)
{
return new RegExp( '^[A-Za-z0-9'+allow+']+$').test(value);
}
By creating a RegExp() object.
function isAlphaNumeric(value, allow) {
var re = new RegExp('^[a-z0-9' + (allow ? allow : '') + ']+$');
return re.test(value);
}
Javascript doesn't handle variables inside strings/regexs directly. You have to create the Regex using the constructor like this:
function isAlphaNumeric(value, allow)
{
var result = new RegExp("^[A-Za-z0-9" + allow + "]+$").test(value);
return result;
}
Tested on: http://jsfiddle.net/ZLdtw/
Check this other SO question for more info on this concatenation.