Convert string to regex using regexp and test values in javascript - javascript

I have a regular expression that is in string form, I want to bind that regex to my grid cell. Such that, now the values in that cell are validated against that regex. I am using RegExp JavaScript library for conversion and testing the value. But it is either returning false everytime or giving me an invalid regex, even for the simplest of the regex used.
This is the method I am using:
addCellValidator(columnObj[0].name, new CellValidator({
isValid: function (value) {
var regex = new RegExp("/^[a-zA-Z\-]+$/");
return value == "" || (regex.test(value));
}
}));
Is it the format or any special pattern required by the RegExp?

While this is valid JavaScript code:
new RegExp("/^[a-zA-Z\-]+$/")
... it doesn't generate the regular expression you think. It's equivalent to this:
/\/^[a-zA-Z-]+$\//
You'll have to:
Strip delimiters
Extract and parse flags, if any, e.g.:
"/^[a-z-]+$/i" ---> new RegExp("^[a-z-]+$", "i")
One more note: there's no point in escaping - with backslash. If want to match a literal - inside a character class you need to put it as first or last item.

You just added the / / to the string, this works:
addCellValidator(columnObj[0].name, new CellValidator({
isValid: function (value) {
var regex = new RegExp("^[a-zA-Z\-]+$");
return value == "" || (regex.test(value)); }
}));

Related

How do I use a regular expression from a string variable

In my current project, I have a CMS that is supplying all the data. One field of that CMS is for regular expressions, which allows me to enter my own specific expressions to check in the front end. My problem is that when I pull the regular expression it is coming through the escaped characters, and I can not seem to find a way to get around this.
The expression that I am using is /^\d+$/. As I mentioned this is stored inside my CMS and I am attempting to use it in the following code:
const re = /^\d+$/;
const rea = new RegExp(this.question.QuestionExpression);
console.log(re);
console.log(rea);
console.log(this.answer)
console.log(re.test(this.answer));
console.log(rea.test(this.answer));
console.log(this.answer.toString().match(this.question.QuestionExpression))
this.question.QuestionExpression is the Regular expression that is coming in from the CMS. The problem is not getting it, but how to interperet once I have it. const re is currently just being used as a test and has no real bearing on the final outcome.
The outcome from the above code is as follows:
/^\d+$/
/\/^\d+$\//
13
true
false
null
As you can see in the second line, it is adding escape characters which are causing it to fail on the 5th line. I am sure that I am missing something simple, but any advice would be greatly appreciated.
You don't include the / at the start and end when you are using a RegExp from a string.
const pattern = new RegExp('^a.*z');
console.log(pattern.test('abcdefghijklmnopqrstuvwxyz'));
console.log(pattern.test('zydhfkjadhsfkjlahsdkla'));
So, if your string is including those slashes, or may include those slashes, simply strip them off:
const strWithSlashes = '/abc/';
const str = strWithSlashes.replace(/(^\/|\/$)/g, '');
console.log(str);
const pattern = new RegExp(str);
console.log(pattern.test('cake abc cookies'));
console.log(pattern.test('cake cookies'));
If your regex from the CMS looks like /^\d+$/ it is likely the string representation of the regex. In contrast, new RegExp() expects a string representing the regex pattern without the leading and trailing /, so you need to strip them:
const fromCMS = '/^\\d+$/'; // escaped `\` so that string becomes `/^\d+$/`
const re1 = /^\d+$/;
const re2 = new RegExp(fromCMS.replace(/^\//, '').replace(/\/$/, ''));
console.log(re1);
console.log(re2);
[ '12', '2x' ].forEach(str => {
console.log(str + ' => re1: ' + re1.test(str) + ', re2: ' + re2.test(str));
});
Output:
/^\d+$/
/^\d+$/
12 => re1: true, re2: true
2x => re1: false, re2: false
In case the regex string from the CMS contains modifiers you can extract that, and supply as a second parameter to the new RegExp()

Converting ## to number regex

I am holding in a field the validation format that I would need.
I need to convert different ## into a regex validation.
Is there a simple replace that can do this for me.
for example, i need to validate the account number.
sometimes it might need to be ###-###, or I'll get ####### or ##-####.
depending what is in the id="validationrule" field
I'm looking for
regex = $('#validationrule').replace("#", "[0/9]");
It also has to take into consideration that sometimes there is a dash in there.
Your question seems to be about creating regexes from a string variable (which you get from an input field that specifies the validation format).
"###-###" might turn into /^\d{3}\-\d{3}$/
"#######" might turn into /^\d{7}$/
If your validation format is built from the 2 characters # and -, this would work:
function createValidationRegEx(format){
format = format
.replace(/[^#\-]/g, '') //remove other chars
.replace(/#/g, '\\d') //convert # to \d
.replace(/\-/g, '\\-'); //convert - to \-
return new RegExp('^' + format + '$', 'g');
}
//create regexes
var format1 = createValidationRegEx('###-###');
var format2 = createValidationRegEx('#######');
//test regexes
console.log(format1.test('123-456')); // true
console.log(format2.test('123-456')); // false
console.log(format1.test('1234567')); // false
console.log(format2.test('1234567')); // true
Please note that you need to pay attention to which characters needs to be escaped when creating regexes from strings. This answer provides more details about how to solve this more generally, if you want to build more complex solutions.
If you are trying to replace the .value of an <input> element you can use .val(function), return replacement string from .replace() inside of function, chain .val() to assign result to regex. Use RegExp constructor with g flag to replace all matches of the RegExp supplied to .replace() to match characters against at string.
var regex = $("#validationrule").val(function(_, val) {
return val.replace("#", "[0/9]");
}).val();
console.log(regex);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<input id="validationrule" value="#">

What is the difference between RegExp("str","i") and '/'+"str"+'/i'

I tried to do a case insensitive regular expression search by creating a string like so:
var regEx = '/'+myStr+'/i';
but when I use it in a search, it always returns -1.
If I use:
var regEx = RegExp(myStr,'i');
it works like a champ.
I'd just like to understand why?
You first example will create a string, not a regular expression object.
var myStr = 'test';
var regEx = '/'+myStr+'/i';
console.log(typeof regEx);//string
Using RegExp will create a regular expression object.
var myStr = 'test';
var regEx = RegExp(myStr,'i');
console.log(typeof regEx);//object
Thus when you try to use the search method, you are searching with a string on slashes on both sides, thus getting -1.
var s = 'just a test string';
console.log(s.search('/test/'));//-1
console.log(s.search(/test/));//7
Of course, the string search method can work with a string, in which case it will search for that specific substring, which in your case does not exist, so it returns the -1 index. In your example slashes were being added to the string, rather than producing the intended regular expression.
In JavaScript, there are two ways of creating a regular expression object (short of using code evaluation), a regular expression literal, and one created by the RegExp constructor.
A regular expression literal has to be defined at compile time, and cannot be constructed from string concatenation.
/test/i
To dynamically create a regular expression at runtime, you have to use the RegExp constructor.
RegExp('test', 'i');

Regex checking lat/lon in JavaScript

I'm such a newb in regex, but still...
I based my test on this post.
I have this simple regex :
^-?([1]?[1-7][1-9]|[1]?[1-8][0]|[1-9]?[0-9])\.{1}\d{1,6}
In Debuggex, if I test it with 88.5 for example, it matches.
In my JS file, I have :
var lonRegex = new RegExp("^-?([1-8]?[1-9]|[1-9]0)\.{1}\d{1,6}");
var check = lonRegex.test(88.5); // hardcoded for demo
console.log(check) // output false
I can't guess why it's always returning me false, whatever the value is a number or a string like "88.5".
You will need to escape some characters when creating a RegExp object from a string. From MDN:
When using the constructor function, the normal string escape rules (preceding special characters with \ when included in a string) are necessary.
In your case, this will work (note the double \ for \d and .):
var lonRegex = new RegExp("^-?([1-8]?[1-9]|[1-9]0)\\.{1}\\d{1,6}");
var check = lonRegex.test(88.5); // hardcoded for demo
console.log(check) // output true

regular expression not working when provided in double quotes in javascript

I am trying to use regular expession in javascript but it is not working. My custom control contains property called RegEx which is provided by user and I need to validate the input value against this regex. As properties in JS will be in double quotes("") the regualr expression fails(case -1). Case 2 succeeds thought both the cases regualr expression is same, the only difference is case- 1 it goes as double quotes. can somebody tell me why it is not working.
RegexExp="/^\d{5}$/"- at my aspx page
var value = "11111";
if(value.toString().search($(element).attr('RegexExp')) != -1)
{
return true;
}
else
{
return false;
}
var reg = /^\d{5}$/;
if(value.toString().search(reg) != -1)
{
return true;
}
else
{
return false;
}
Do this instead:
var reg = new RegExp($(element).attr('RegexExp'));
Update: you also need to strip the / characters, as these shouldn't be given to the RegExp constructor:
var regexExp = $(element).attr('RegexExp');
var reg = new RegExp(regexExp.substring(1, regexExp.length - 1));
I assume that the code that you posted is part of the function from the return statements, but if it is not, your first problem is that return is not allowed to be used out side of functions.
In any case, try the following. You can create a RegExp from a string by using its formal constructor
value.search(new RegExp($(element).attr('RegexExp')));
Also, you do not need to use toString() on value since it is already a string and your code is unnecessarily verbose. The following is equivalent to your first if else statement
return value.search(new RegExp($(element).attr('RegexExp'))) != -1;
Edit:
If you want to be able to pass in an expression as "/[expression]/" or "/[expression]/gi", you can do the following:
var toRegExp = function(regexString) {
var expression = regexString.substr(1), // remove first '/'
closingSlash = expression.lastIndexOf("/"); // find last '/'
return new RegExp(
// Expression: remove everything after last '/'
expression.substr(0, closingSlash),
// Flags: get everything after the last '/'
expression.substr(closingSlash+1)
);
}
....
value.search( toRegExp($(element).attr('RegexExp')) );
First, don't use a custom attribute to hold a regular expression. Second, "RegexExp" is redundant — that's like saying "regular expression expression". Third, to convert from a String to a RegExp, you have to wrap the string with new RegExp(); JavaScript is not weakly typed. That said, assuming that the regular expression isn't being set server-side, I'd recommend using jQuery's data API. It has the added advantage that it can store regular expression objects directly.
To set:
jQuery.data($(element).get(0), "regexp", /^\d{5}$/);
To get:
jQuery.data($(element).get(0), "regexp");
But ultimately, what you really want is the jQuery Validation plugin. It does everything you need and then some. Incidentally, it uses the data API internally to work its magic.
Documentation
The /.../ syntax is used to declare a regular expression object in Javascript, so you shouldn't use that to specify a regular expression pattern, it should be just regexp="^\d{5}$" as the attribute.
The search method takes a regular expression object as parameter, so you have to create a regular expression object from the string that you get from the attribute:
var reg = new RegExp($(element).attr('regexp'));
if (value.toString().search(reg) != -1) {
(You see the similarity with your second case?)
Or as a single expression:
if (value.toString().search(new RegExp($(element).attr('regexp'))) != -1) {

Categories

Resources