Javascript: Convert a String to Regular Expression - javascript

I want to convert a string that looks like a regular expression...into a regular expression.
The reason I want to do this is because I am dynamically building a list of keywords to be used in a regular expression. For example, with file extensions I would be supplying a list of acceptable extensions that I want to include in the regex.
var extList = ['jpg','gif','jpg'];
var exp = /^.*\.(extList)$/;
Thanks, any help is appreciated

You'll want to use the RegExp constructor:
var extList = ['jpg','gif','jpg'];
var reg = new RegExp('^.*\\.(' + extList.join('|') + ')$', 'i');
MDC - RegExp

var extList = "jpg gif png".split(' ');
var exp = new RegExp( "\\.(?:"+extList.join("|")+")$", "i" );
Note that:
You need to double-escape backslashes (once for the string, once for the regexp)
You can supply flags to the regex (such as case-insensitive) as strings
You don't need to anchor your particular regex to the start of the string, right?
I turned your parens into a non-capturing group, (?:...), under the assumption that you don't need to capture what the extension is.
Oh, and your original list of extensions contains 'jpg' twice :)

You can use the RegExp object:
var extList = ['jpg','gif','jpg'];
var exp = new RegExp("^.*\\.(" + extList.join("|") + ")$");

Related

Turning a regex returned as a string from an API into a valid RegEx object in JavaScript

I'm fetching a regular expression from an external API, and it comes back as a string. I want to use the regex for address validation, but I can't seem to properly escape the unwanted characters after calling new RegExp() on the string.
Here's the regex I want to use:
console.log(regexFromAPI);
Output
/((\W|^)box\s+(#\s*)?\d+|post\s+office|(\W|^)p\.?\s*o\.?\s+(#\s*)?\d+)/i
However, I can't use that -- I need it to actually be a regex first.
If I do, for example:
const pattern = new RegExp(regexFromAPI);
and then:
console.log(pattern);
I get the following:
Output
//((W|^)boxs+(#s*)?d+|posts+office|(W|^)p.?s*o.?s+(#s*)?d+)/i/
My question is... why is this happening, and how can I avoid it? I want to use my string literal as a regex.
Thanks in advance.
The RegExp constructor does not expect a string with / delimiters, nor with options past the final /. If you do that, the pattern generated from calling new RegExp with it will result in one that matches a string which starts with a literal forward slash /, and ends with a forward slash / followed by the flag characters (here, i).
Instead, you should pass the pattern string without / delimiters, and pass the flags as the second argument - you can extract these easily by using another regular expression:
const fullPatternStr = String.raw`/((\W|^)box\s+(#\s*)?\d+|post\s+office|(\W|^)p\.?\s*o\.?\s+(#\s*)?\d+)/i`;
const [, pattern, flags] = fullPatternStr.match(/\/(.*)\/([a-z]*)/);
const regex = new RegExp(pattern, flags);
console.log(regex);
Take off the slashes and flags, then reconstruct it:
const str = String.raw`/((\W|^)box\s+(#\s*)?\d+|post\s+office|(\W|^)p\.?\s*o\.?\s+(#\s*)?\d+)/i`;
let regexBody = str.slice(1, str.lastIndexOf("/"));
let flags = str.split("/")[str.split("/").length - 1];
let regex = new RegExp(regexBody, flags);
console.log(regex);

RegEx javascript not matching correctly

I have a small javascript funtcion :
function GetFilteredListLimited(event) {
var $source = $(event.target);
var $Pattern = event.data.Pattern;
var RE = new RegExp($Pattern, 'i');
if (RE.test($source.val())) {
console.log('RegEx match');
}
};
The pattern used is:
^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$
Which should match most email-addresses.
Using http://regexpal.com/ I can see that the Pattern is correct. But for some weird reason the script already matches at the 4th character after #
abc#abcd should not give a match, but is does.
Any suggestions ?
You need to be aware of RegExp constructor where escaped characters must be double-escaped. So, your regex string passed to the RegExp constructor should look like:
^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,4}$
The fix can be introduced like this:
var RE = new RegExp($Pattern.replace(/\\/g, '\\\\'), 'i');
It will work if the escape symbols are used consistently.

Javascript - Why is my RegEx for dd.mm.yyyy - dd.mm.yyyy not working?

I have written following code:
var date_regex = new RegExp("\d{2}[./-]\d{2}[./-]\d{4}", "gi");
var period = "27.03.2014 - 24.04.2014";
console.log(date_regex.exec(period));
I get console log : null.
I checked my code on this site and it says valid. What is wrong? Thanks for help!
\d{2}[./-]\d{2}[./-]\d{4}
Debuggex Demo of my RegEx
You need to escape your backslashes:
var date_regex = new RegExp("\\d{2}[./-]\\d{2}[./-]\\d{4}", "gi");
Just as a side note, you can avoid matching strings with mismatched delimiters such as "27.01-1444" by capturing the first delimiter and matching the same one for the second delimiter via \1:
var date_regex = new RegExp("\\d{2}([./-])\\d{2}\\1\\d{4}", "gi");
You are creating your regex from a string, so you need to escape the backslashes:
var date_regex = new RegExp("\\d{2}[./-]\\d{2}[./-]\\d{4}", "gi");
Or it's less complicated to use a regex literal:
var date_regex = /\d{2}[./-]\d{2}[./-]\d{4}/gi;
When creating a regular expression object (as opposed to the literal) with a string, you need to double escape slashes:
var date_regex = new RegExp("\\d{2}[./-]\\d{2}[./-]\\d{4}", "gi");
You'll discover that logging date_regex results in /d{2}[./-]d{2}[./-]d{4}/gi - not what we wanted!
However, you only need to use a string under certain conditions:
The regex involves a variable
The regex is formed in a loop (string prevents recompilation)
Thus, you'd be better off using a literal in this case:
var date_regex = /\d{2}[./-]\d{2}[./-]\d{4}/gi;
See MDN for more details on creating RegExp objects.
Combine the given answers and use .match to return all matches in an array.
var date_regex = /\d{2}[./-]\d{2}[./-]\d{4}/gi;
var range = "27.03.2014 - 24.04.2014";
console.log( range.match(date_regex) ); // [ "27.03.2014", "24.04.2014" ]

Regexp for floating number

I found this regexp for validating floats. But I cant see how 2-1 will accepted. The below evaluates to true. I can't use parseFloat because I need to be able to accept "," instead of "." also. I wrote re2, same result though.
var re1 = new RegExp("^[-+]?[0-9]*\.?[0-9]+$");
console.log(re1.test("2-1"));
var re2 = new RegExp("^([0-9]+)\.([0-9]+)$");
console.log(re2.test("2-1"));
If you generate the regex using the constructor function, you have to to escape the backslash, i.e. \ becomes \\:
var re1 = new RegExp("^[-+]?[0-9]*\\.?[0-9]+$");
Another option is to use the literal syntax which doesn't require escaping:
var re1 = /^[-+]?[0-9]*\.?[0-9]+$/
Sometimes when you create a regex string, you even have to escape the backslash; this can of course be done with a backslash, so the final regex looks something like "\\.*", etc.
Doing this, I was able to get the correct results, as seen here:
var re1 = new RegExp("^[-+]?[0-9]*\\.?[0-9]+$");
console.log(re1.test("2-1"));
var re2 = new RegExp("^([0-9]+)\\.([0-9]+)$");
console.log(re2.test("2-1"));
console.log(re1.test("2.1"));
console.log(re2.test("2.1"));​
What about replacing a comma (",") with a period (".") and then using parseFloat?

Passing regex modifier options to RegExp object

I am trying to create something similar to this:
var regexp_loc = /e/i;
except I want the regexp to be dependent on a string, so I tried to use new RegExp but I couldn't get what i wanted.
Basically I want the e in the above regexp to be a string variable but I fail with the syntax.
I tried something like this:
var keyword = "something";
var test_regexp = new RegExp("/" + keyword + "/i");
Basically I want to search for a sub string in a larger string then replace the string with some other string, case insensitive.
regards,
alexander
You need to pass the second parameter:
var r = new RegExp(keyword, "i");
You will also need to escape any special characters in the string to prevent regex injection attacks.
You should also remember to watch out for escape characters within a string...
For example if you wished to detect for a single number \d{1} and you did this...
var pattern = "\d{1}";
var re = new RegExp(pattern);
re.exec("1"); // fail! :(
that would fail as the initial \ is an escape character, you would need to "escape the escape", like so...
var pattern = "\\d{1}" // <-- spot the extra '\'
var re = new RegExp(pattern);
re.exec("1"); // success! :D
When using the RegExp constructor, you don't need the slashes like you do when using a regexp literal. So:
new RegExp(keyword, "i");
Note that you pass in the flags in the second parameter. See here for more info.
Want to share an example here:
I want to replace a string like: hi[var1][var2] to hi[newVar][var2].
and var1 are dynamic generated in the page.
so I had to use:
var regex = new RegExp("\\\\["+var1+"\\\\]",'ig');
mystring.replace(regex,'[newVar]');
This works pretty good to me. in case anyone need this like me.
The reason I have to go with [] is var1 might be a very easy pattern itself, adding the [] would be much accurate.
var keyword = "something";
var test_regexp = new RegExp(something,"i");
You need to convert RegExp, you actually can create a simple function to do it for you:
function toReg(str) {
if(!str || typeof str !== "string") {
return;
}
return new RegExp(str, "i");
}
and call it like:
toReg("something")

Categories