Matching regular expression string in Javascript - javascript

Does anyone know how to find regular expression string from javascript code?
e.g.
var pattern = /some regular expression/;
Is it possible to to with regular expression :) ?

If I got your question right, and you need a regular expression which would find all the regular expressions in a JavaScript program, then I don't think it is possible. A regular expression in JavaScript does not have to use the // syntax, it can be defined as a string. Even a full-blown JavaScript parser would not be smart enough to detect a regular expression here, for instance:
var re = "abcde";
var regexClass = function() { return RegExp; }
var regex = new regexClass()(re);
So I would give up this idea unless you want to cover only a few very basic cases.

You want a regex to match a regex? Crazy. This might cover the simplest cases.
new RegExp("\/.+\/")
However, I peeked into the Javascript Textmate bundle and is has 2 regex for finding a regex start and end.
begin = '(?<=[=(:]|^|return)\s*(/)(?![/*+{}?])'
end = '(/)[igm]*';
Which you could probably use as inspiration for toward your goal.

Thanks for answers I have found also that it is nearly impossible task to do, but here is my regex which parses source code just fine:
this.mainPattern = new RegExp(//single line comment
"(?://.*$)|"+
//multiline comment
"(/\\*.*?($|\\*/))"+
//single or double quote strings
"|(?:(?:\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")|(?:'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'))"+
//regular expression literal in javascript code
"|(?:(?:[/].+[/])[img]?[\\s]?(?=[;]|[,]|[)]))"+
//brackets
"|([{]|[(]|[\[])|([}]|[)]|[\\]])", 'g');

Related

How to convert a .NET URL regex to a Javascript URL regex?

I am using in .Net the [Url(UrlOptions.DisallowProtocol)] data annotation attribute which checks URL regex (no mandatory for https/http or www).
The code of this attribute looks like this:
string const regex = new RegExp('^((https?|ftp):\/\/)?(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:)*#)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|([a-zA-Z][\-a-zA-Z0-9]*)|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)|\/|\?)*)?$');
I want to convert it to JS validation but facing lots of difficulties because this is a long validation.
Is there any tool or any easy way to convert this regex to work in JS?
The regular expression seems to work in Javascript to some extent without any modification - see regex101 demo. Just remember to escape all backslashes (\\ in place of \) and single quotes ('' instead of ') if defining it in a single-quoted Javascript string:
var jsRegex = new RegExp('^((https?|ftp):\\/\\/)?(((([a-zA-Z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-fA-F]{2})|[!\\$&''\\(\\)\\*\\+,;=]|:)*#)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|([a-zA-Z][\\-a-zA-Z0-9]*)|((([a-zA-Z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-zA-Z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-zA-Z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-zA-Z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-zA-Z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-zA-Z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-zA-Z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-zA-Z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-zA-Z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-fA-F]{2})|[!\\$&''\\(\\)\\*\\+,;=]|:|#)+(\\/(([a-zA-Z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-fA-F]{2})|[!\\$&''\\(\\)\\*\\+,;=]|:|#)*)*)?)?(\\?((([a-zA-Z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-fA-F]{2})|[!\\$&''\\(\\)\\*\\+,;=]|:|#)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-zA-Z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-fA-F]{2})|[!\\$&''\\(\\)\\*\\+,;=]|:|#)|\\/|\\?)*)?$', 'i');
// ...or...
var jsRegex = /^((https?|ftp):\/\/)?(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:)*#)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|([a-zA-Z][\-a-zA-Z0-9]*)|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)|\/|\?)*)?$/i;
Note: The i modifier is assuming this needs case-insensitive matching.
(If the above isn't sufficient, please be more specific about what isn't working.)
Is there any tool or any easy way to convert this regex to work in JS?
The only generic tool I'm aware of that supposedly converts between regex flavors is RegexBuddy - but it is paid for software (€29.95) - although if for any reason it didn't work you could get a refund.
var YourRegEx = #"^((https?|ftp):\/\/)?(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:)*#)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|([a-zA-Z][\-a-zA-Z0-9]*)|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-fA-F]{2})|[!\$&'\(\)\*\+,;=]|:|#)|\/|\?)*)?$";
var Ismatch = Regex.Match(input, YourRegEx , RegexOptions.IgnoreCase);
if (Ismatch .Success)
{
// does match
}
You can Try this as will put your regex in #""

How to make this youtube videoId parsing RegExp work in JS?

I'm trying to use this great RegEx presented here for grabbing a video id from any youtube type url:
parse youtube video id using preg_match
// getting our youtube url from an input field.
var yt_url = $('#yt_url').val();
var regexp = new RegExp('%(?:youtube(?:-nocookie)?\\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\\.be/)([^"&?/ ]{11})%','i');
var videoId = yt_url.match( regexp ) ;
console.log('vid: '+videoId);
My console is always giving me a null videoId though. Am I incorrectly escaping something in my regexp var? I added the a second backslash to escape the single backslashes already.
Scratching my head?
% are delimiters for the PHP you got the link from, Javascript does not expect delimiters when using new RegExp(). Also, it looks like \\. should probably be replaced with \. Try:
var regexp = new RegExp('(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})','i');
Also, you can create a regular expression literally by using Javascript's /.../ delimiters, but then you'll need to escape all of your /s:
var regexp = /(?:youtube(?:-nocookie)?\.com\/(?:[^/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\\.be\/)([^"&?\/ ]{11})/i;
Documentation
Update:
A quick update to address the comment on efficiency for literal expressions (/ab+c/) vs. constructors (new RegExp("ab+c")). The documentation says:
Regular expression literals provide compilation of the regular expression when the script is loaded. When the regular expression will remain constant, use this for better performance.
And:
Using the constructor function provides runtime compilation of the regular expression. Use the constructor function when you know the regular expression pattern will be changing, or you don't know the pattern and are getting it from another source, such as user input.
Since your expression will always be static, I would say creating it literally (the second example) would be slightly faster since it is compiled when loaded (however, don't confuse this into thinking it won't be creating a RegExp object). This small difference is confirmed with a quick benchmark test.

XRegExp to replace Unicode characters in IE

I developed a javascript function to clean a range of Unicode characters. For example, "ñeóñú a1.txt" => "neonu a1.txt". For this, I used a regular expression:
var = new RegExp patternA ("[\\u0300-\\u036F]", "g");
name = name.replace (patternA,'');
But it does not work properly in IE. If my research is correct, IE does not detect Unicode in the same way. I'm trying to make an equivalent function using the library XRegExp (http://xregexp.com/), which is compatible with all browsers, but I don't know how to write the Unicode pattern so XRegExp works in IE.
One of the failed attemps:
XRegExp.replace(name,'\\u0300-\\u036F','');
How can I build this pattern?
The value provided as the XRegExp.replace method's second argument should be a regular expression object, not a string. The regex can be built by the XRegExp or the native RegExp constructor. Thus, the following two lines are equivalent:
name = name.replace(/[\u0300-\u036F]/g, '');
// Is equivalent to:
name = XRegExp.replace(name, /[\u0300-\u036F]/g, '');
The following line you wrote, however, is not valid:
var = new RegExp patternA ("[\\u0300-\\u036F]", "g");
Instead, it should be:
var patternA = new RegExp ("[\\u0300-\\u036F]", "g");
I don't know if that is the source of your problem, but perhaps. For the record, IE's Unicode support is as good or better than other browsers.
XRegExp can let you identify your block by name, rather than using magic numbers. XRegExp('[\\u0300-\\u036F]') and XRegExp('\\p{InCombiningDiacriticalMarks}') are exactly equivalent. However, the marks in that block are a small subset of all combining marks. You might actually want to match something like XRegExp('\\p{M}'). However, note that simply removing marks like you're doing is not a safe way to remove diacritics. Generally, what you're trying to do is a bad idea and should be avoided, since it will often lead to wrong or unintelligible results.

Javascript regular expressions: substituting variables

I need a hand to sub a variable into a regular expression
this line works fine:
subject = subject.replace(/<a title="Smile"><img.+?<\/a>/g, emoticons[1]);
I need switch the word "Smile" for a variable.
I have tried a few different configurations like:
subject = subject.replace(/<a title="'+emoLanguage[0]+'"><img.+?<\/a>/g, emoticons[1]);
but I can't get the variable to work.
Whats the trick??
First I would say that you probably shouldn't use a regular expression to parse/fix HTML. That being said, this should work:
var re = new RegExp("<a title=\"" + emoLanguage[0] + "\"><img.+?</a>", "g");
subject = subject.replace(re, emoticons[1]);
A better solution would be to use jQuery. The solution is much prettier:
jQuery("a[title='" + emoLanguage[0] + "']").replaceWith(emoticons[1]);
This assumes that the data in emoticons[1] is HTML.
Of course, importing jQuery for just this little thing is probably overkill, but I'm sure that you'll find that it will probably make other things in your Javascript much more easier and elegant.
Use the new Regexp() constructor to create the regular expression, instead of a literal regexp.
Note that you’ll have to properly escape your string, since many characters have special meaning in a regexp.
You have to use the RegExp object cobnstructor in such case:
var pattern = new RegExp('<a title="'+emoLanguage[0]+'"><img.+?</a>',"g");
subject = subject.replace(pattern, emoticons[1]);

Invalid regular expression error

I'm trying to retrieve the category part this string "property_id=516&category=featured-properties", so the result should be "featured-properties", and I came up with a regular expression and tested it on this website http://gskinner.com/RegExr/, and it worked as expected, but when I added the regular expression to my javascript code, I had a "Invalid regular expression" error, can anyone tell me what is messing up this code?
Thanks!
var url = "property_id=516&category=featured-properties"
var urlRE = url.match('(?<=(category=))[a-z-]+');
alert(urlRE[0]);
Positive lookbehinds (your ?<=) are not supported in JavaScript environments that do not comply with ECMAScript 2018 standard, which is causing your RegEx to fail.
You can mimic them in a whole bunch of different ways, but this might be a simpler RegEx to get the job done for you:
var url = "property_id=516&category=featured-properties"
var urlRE = url.match(/category=([^&]+)/);
// urlRE => ["category=featured-properties","featured-properties"]
// urlRE[1] => "featured-properties"
That's a super-simple example, but searching StackOverflow for a RegEx pattern to parse URL parameters will turn up more robust examples if you need them.
The syntax is messing up your code.
var urlRE = url.match(/category=([a-z-]+)/);
alert(urlRE[1]);
If you want to parse URL parameters, you can use the getParameterByName() function from this site:
http://james.padolsey.com/javascript/bujs-1-getparameterbyname/
In any case, as already mentioned, regular expressions in JavaScript are not plain strings:
https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
var url = "property_id=516&category=featured-properties",
urlRE = url.match(/(category=)([a-z-]+)/i); //don't forget i if you want to match also uppercase letters in category "property_id=516&category=Featured-Properties"
//urlRE = url.match(/(?<=(category=))[a-z-]+/i); //this is a mess
alert(urlRE[2]);

Categories