Not a lot of experience in RegEx stuff.
I have the following in java script which works perfectly fine.
The following pattern is used allow only alpha numeric
var valid = /^[A-Za-z0-9]+$/.test("a"); // returns true
var valid = /^[A-Za-z0-9]+$/.test("#"); // returns false
I am using the pattern part "^[A-Za-z0-9]" in some other places of the code and was asked to use the part "^[A-Za-z0-9]" in a variable and use it so that it is not repetitive. The following is a modification to the above:
var regExPart= "^[A-Za-z0-9]";
var regExString = ("/" + regExPart+ "+$/".replace(/\"/g, "")); // replacing the quotes
var regExp = new RegExp(regExString); // results in /^[A-Za-z0-9]+$/
var valid = regExp.test(charValue); // charValue could be any keyvalue "a" or "#"
//the above returns false for "a"
//the above returns false for "#"
I am writing this in a keypress event to allow only alpha numeric
keypressValidation: function (e) {
var charCode = (e.which) ? e.which: event.keyCode;
var charValue = String.fromCharCode(charCode);
var valid = return /^[A-Za-z0-9]+$/.test(charValue);
if (!valid)
{
//prevent default (don't allow/ enter the value)
}
Not sure why. What am I missing in this. Need to return true for "a" and false for "#" for both the approaches. Any help/ suggestion would be of great help. Thank in advance.
For the RegExp class constructor, you do not need to specify forward slashes /.
var regExPart= "^[A-Za-z0-9]";
var regExp = new RegExp(regExPart + "+$"); // results in /^[A-Za-z0-9]+$/
console.log('a', regExp.test('a'))
console.log('#', regExp.test('#'))
It is not a must to contain '/'s in regexp
new RegExp("^[0-9a-zA-Z]$").test('a')
return true
new RegExp("^[0-9a-zA-Z]$").test('#')
return false
So just do
var rex="^[0-9a-zA-Z]$"
And you can use it anywhere. Tested in Chrome console.
I've made an example using your regex of what it should do, i think the way you were building your regex was not helping. You don't need to create a string and then create a new regex object , you can use /regex part/.
Anyways here is a working example.
function keypress(e) {
// Get the current typed key
var keynum = e.key;
// this regex only allow character between a and z and 0 and 9
var regex = /^[a-zA-Z0-9]+$/;
// we check if the current key matches our regex
if(!keynum.match(regex) ) {
// it doesn't ? well we stop the event from happening
e.preventDefault();
}
}
<input type="text" onkeypress="keypress(event)">
Related
I tried to construct a working regex for the mentioned scenario but it's not working.
It should restrict the MAC IDs with leading "01" (01-xx-xx-xx-xx-xx). eg
01:AA:BB:05:31:01 <- Not valid.
21:51:51:31:01:AA <- Valid.
It should restrict FF:FF:FF:FF:FF:FF full match.
What I have done so far is here.
^((?!01|FF|88|87|ff|00)[0-9a-fA-F]{2}([:-]|$)){6}$
If you want to escape anything that begins with 01|FF|88|87|ff|00 use this
pattern=/^(?=[^01|FF|88|87|ff|00])([0-9a-fA-F]{2}[:]){5}[0-9a-fA-F]{2}/gm
if you want to escape beginning 01|88|87|00 and only a full patter FF use this one instead
pattern=/^(?!01|88|87|00|FF:FF:FF:FF:FF:FF)([0-9a-fA-F]{2}[:]){5}[0-9a-fA-F]{2}/
You can try something like this:
var macAddressAllowed = function(macAddr) {
// regEX for valid MAC address
var regExp = "^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$";
var regex = new RegExp(regExp);
var validMac = regex.test(macAddr);
if(!validMac){
return false;
}else{
macAddr = macAddr ? macAddr.toLowerCase() : '';
var macAllowed = (macAddr === 'ff:ff:ff:ff:ff:ff' || macAddr.split(':')[0] === '01');
return macAllowed ? false: true;
}
};
I am designing a regular expression tester in HTML and JavaScript. The user will enter a regex, a string, and choose the function they want to test with (e.g. search, match, replace, etc.) via radio button and the program will display the results when that function is run with the specified arguments. Naturally there will be extra text boxes for the extra arguments to replace and such.
My problem is getting the string from the user and turning it into a regular expression. If I say that they don't need to have //'s around the regex they enter, then they can't set flags, like g and i. So they have to have the //'s around the expression, but how can I convert that string to a regex? It can't be a literal since its a string, and I can't pass it to the RegExp constructor since its not a string without the //'s. Is there any other way to make a user input string into a regex? Will I have to parse the string and flags of the regex with the //'s then construct it another way? Should I have them enter a string, and then enter the flags separately?
Use the RegExp object constructor to create a regular expression from a string:
var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);
or
var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);
Here is a one-liner: str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
I got it from the escape-string-regexp NPM module.
Trying it out:
escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}
console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/
Using tagged template literals with flags support:
function str2reg(flags = 'u') {
return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
, flags)
}
function evalTemplate(strings, ...values) {
let i = 0
return strings.reduce((str, string) => `${str}${string}${
i < values.length ? values[i++] : ''}`, '')
}
console.log(str2reg()`example.com`)
// => /example\.com/u
Use the JavaScript RegExp object constructor.
var re = new RegExp("\\w+");
re.test("hello");
You can pass flags as a second string argument to the constructor. See the documentation for details.
In my case the user input somethimes was sorrounded by delimiters and sometimes not. therefore I added another case..
var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
// the parsed pattern had delimiters and modifiers. handle them.
var regexp = new RegExp(regParts[1], regParts[2]);
} else {
// we got pattern string without delimiters
var regexp = new RegExp(inputstring);
}
Try using the following function:
const stringToRegex = str => {
// Main regex
const main = str.match(/\/(.+)\/.*/)[1]
// Regex options
const options = str.match(/\/.+\/(.*)/)[1]
// Compiled regex
return new RegExp(main, options)
}
You can use it like so:
"abc".match(stringToRegex("/a/g"))
//=> ["a"]
Here is my one liner function that handles custom delimiters and invalid flags
// One liner
var stringToRegex = (s, m) => (m = s.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3].split('').filter((i, p, s) => s.indexOf(i) === p).join('')) : new RegExp(s);
// Readable version
function stringToRegex(str) {
const match = str.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/);
return match ?
new RegExp(
match[2],
match[3]
// Filter redundant flags, to avoid exceptions
.split('')
.filter((char, pos, flagArr) => flagArr.indexOf(char) === pos)
.join('')
)
: new RegExp(str);
}
console.log(stringToRegex('/(foo)?\/bar/i'));
console.log(stringToRegex('#(foo)?\/bar##gi')); //Custom delimiters
console.log(stringToRegex('#(foo)?\/bar##gig')); //Duplicate flags are filtered out
console.log(stringToRegex('/(foo)?\/bar')); // Treated as string
console.log(stringToRegex('gig')); // Treated as string
I suggest you also add separate checkboxes or a textfield for the special flags. That way it is clear that the user does not need to add any //'s. In the case of a replace, provide two textfields. This will make your life a lot easier.
Why? Because otherwise some users will add //'s while other will not. And some will make a syntax error. Then, after you stripped the //'s, you may end up with a syntactically valid regex that is nothing like what the user intended, leading to strange behaviour (from the user's perspective).
This will work also when the string is invalid or does not contain flags etc:
function regExpFromString(q) {
let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
if (flags === q) flags = '';
let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
try { return new RegExp(pattern, flags); } catch (e) { return null; }
}
console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));
Thanks to earlier answers, this blocks serves well as a general purpose solution for applying a configurable string into a RegEx .. for filtering text:
var permittedChars = '^a-z0-9 _,.?!#+<>';
permittedChars = '[' + permittedChars + ']';
var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);
log.debug ('strFilterRegEx: ' + strFilterRegEx);
strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,.?!#+]/ig, '');
You can ask for flags using checkboxes then do something like this:
var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);
Safer, but not safe. (A version of Function that didn't have access to any other context would be good.)
const regexp = Function('return ' + string)()
I found #Richie Bendall solution very clean. I added few small modifications because it falls appart and throws error (maybe that's what you want) when passing non regex strings.
const stringToRegex = (str) => {
const re = /\/(.+)\/([gim]?)/
const match = str.match(re);
if (match) {
return new RegExp(match[1], match[2])
}
}
Using [gim]? in the pattern will ignore any match[2] value if it's invalid. You can omit the [gim]? pattern if you want an error to be thrown if the regex options is invalid.
I use eval to solve this problem.
For example:
function regex_exec() {
// Important! Like #Samuel Faure mentioned, Eval on user input is a crazy security risk, so before use this method, please take care of the security risk.
var regex = $("#regex").val();
// eval()
var patt = eval(userInput);
$("#result").val(patt.exec($("#textContent").val()));
}
I am designing a regular expression tester in HTML and JavaScript. The user will enter a regex, a string, and choose the function they want to test with (e.g. search, match, replace, etc.) via radio button and the program will display the results when that function is run with the specified arguments. Naturally there will be extra text boxes for the extra arguments to replace and such.
My problem is getting the string from the user and turning it into a regular expression. If I say that they don't need to have //'s around the regex they enter, then they can't set flags, like g and i. So they have to have the //'s around the expression, but how can I convert that string to a regex? It can't be a literal since its a string, and I can't pass it to the RegExp constructor since its not a string without the //'s. Is there any other way to make a user input string into a regex? Will I have to parse the string and flags of the regex with the //'s then construct it another way? Should I have them enter a string, and then enter the flags separately?
Use the RegExp object constructor to create a regular expression from a string:
var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);
or
var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);
Here is a one-liner: str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
I got it from the escape-string-regexp NPM module.
Trying it out:
escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}
console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/
Using tagged template literals with flags support:
function str2reg(flags = 'u') {
return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
, flags)
}
function evalTemplate(strings, ...values) {
let i = 0
return strings.reduce((str, string) => `${str}${string}${
i < values.length ? values[i++] : ''}`, '')
}
console.log(str2reg()`example.com`)
// => /example\.com/u
Use the JavaScript RegExp object constructor.
var re = new RegExp("\\w+");
re.test("hello");
You can pass flags as a second string argument to the constructor. See the documentation for details.
In my case the user input somethimes was sorrounded by delimiters and sometimes not. therefore I added another case..
var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
// the parsed pattern had delimiters and modifiers. handle them.
var regexp = new RegExp(regParts[1], regParts[2]);
} else {
// we got pattern string without delimiters
var regexp = new RegExp(inputstring);
}
Try using the following function:
const stringToRegex = str => {
// Main regex
const main = str.match(/\/(.+)\/.*/)[1]
// Regex options
const options = str.match(/\/.+\/(.*)/)[1]
// Compiled regex
return new RegExp(main, options)
}
You can use it like so:
"abc".match(stringToRegex("/a/g"))
//=> ["a"]
Here is my one liner function that handles custom delimiters and invalid flags
// One liner
var stringToRegex = (s, m) => (m = s.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3].split('').filter((i, p, s) => s.indexOf(i) === p).join('')) : new RegExp(s);
// Readable version
function stringToRegex(str) {
const match = str.match(/^([\/~#;%#'])(.*?)\1([gimsuy]*)$/);
return match ?
new RegExp(
match[2],
match[3]
// Filter redundant flags, to avoid exceptions
.split('')
.filter((char, pos, flagArr) => flagArr.indexOf(char) === pos)
.join('')
)
: new RegExp(str);
}
console.log(stringToRegex('/(foo)?\/bar/i'));
console.log(stringToRegex('#(foo)?\/bar##gi')); //Custom delimiters
console.log(stringToRegex('#(foo)?\/bar##gig')); //Duplicate flags are filtered out
console.log(stringToRegex('/(foo)?\/bar')); // Treated as string
console.log(stringToRegex('gig')); // Treated as string
I suggest you also add separate checkboxes or a textfield for the special flags. That way it is clear that the user does not need to add any //'s. In the case of a replace, provide two textfields. This will make your life a lot easier.
Why? Because otherwise some users will add //'s while other will not. And some will make a syntax error. Then, after you stripped the //'s, you may end up with a syntactically valid regex that is nothing like what the user intended, leading to strange behaviour (from the user's perspective).
This will work also when the string is invalid or does not contain flags etc:
function regExpFromString(q) {
let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
if (flags === q) flags = '';
let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
try { return new RegExp(pattern, flags); } catch (e) { return null; }
}
console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));
Thanks to earlier answers, this blocks serves well as a general purpose solution for applying a configurable string into a RegEx .. for filtering text:
var permittedChars = '^a-z0-9 _,.?!#+<>';
permittedChars = '[' + permittedChars + ']';
var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);
log.debug ('strFilterRegEx: ' + strFilterRegEx);
strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,.?!#+]/ig, '');
You can ask for flags using checkboxes then do something like this:
var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);
Safer, but not safe. (A version of Function that didn't have access to any other context would be good.)
const regexp = Function('return ' + string)()
I found #Richie Bendall solution very clean. I added few small modifications because it falls appart and throws error (maybe that's what you want) when passing non regex strings.
const stringToRegex = (str) => {
const re = /\/(.+)\/([gim]?)/
const match = str.match(re);
if (match) {
return new RegExp(match[1], match[2])
}
}
Using [gim]? in the pattern will ignore any match[2] value if it's invalid. You can omit the [gim]? pattern if you want an error to be thrown if the regex options is invalid.
I use eval to solve this problem.
For example:
function regex_exec() {
// Important! Like #Samuel Faure mentioned, Eval on user input is a crazy security risk, so before use this method, please take care of the security risk.
var regex = $("#regex").val();
// eval()
var patt = eval(userInput);
$("#result").val(patt.exec($("#textContent").val()));
}
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;
}}
This method is to prevent users from entering anything but numbers and "allowed characters." Allowed characters are passed as the parameter allowedchars.
So far, the method prevents number entries but the allowedchars doesn't work (tried with passing "-" (hyphen) and "." (period)). So I'm assuming my dynamic regex construction isn't correct. Help?
Thanks in advance!
numValidate : function (evt, allowedchars) {
var theEvent, key, regex,
addToRegex = allowedchars;
theEvent = evt || window.event;
key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = new RegExp('/^[0-9' + addToRegex + ']$/');
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault) {
theEvent.preventDefault();
}
}
}
(ps. jQuery solutions are fine too)
1. When you construct via new RegExp, there's no need to include the surrounding /s.
var regex = new RegExp('^[0-9' + addToRegex + ']$');
2. But if addToRegex contains ] or -, the resulting regex may become invalid or match too much. So you need to escape them:
var regex = new RegExp('^[0-9' + addToRegex.replace(/([\-\]])/g, '\\$1') + ']$');
3. But since you are checking against 1 character anyway, it may be easier to avoid regex.
var pass = ("0123456789" + addToRegex).indexOf(key);
if (pass == -1) {
...