Creating RegEx from other RegEx - javascript

I really like Regular Expressions. I was wondering if this kind of things can be done in JavaScript.
Imagine that you want to match the words foo and bar, but only when they are followed by "?" Or "!". I know that this simple case could be done with x(?=y), but my intention here is to know if you can place one RegEx inside another, as it would be great for more difficult scenarios.
I mean something like this:
var regex1 = /foo|bar/;
var regex2 = /{regex1}[\?\!]/;
This would simplify very complex regexes and would make some patters reusable without having to write the same patterns every time you need it. It would be something like a RegEx variable, if that makes sense.
Is it possible?

Use RegExp constructor.
new RegExp('(?:' + regex1.source + ')[?!]')
regex1.source will give the actual regex as string without the delimiters and flags which then can be passed to the RegExp constructor to create new regex.
Also, note that there is no need to escape ? and ! when used inside character class.
var regex1 = /foo|bar/;
var regex = new RegExp('(?:' + regex1.source + ')[?!]')
console.log(regex);

Related

Javascript: Difference in Regex String and Regex [duplicate]

This question already has answers here:
Differences between Javascript regexp literal and constructor
(2 answers)
Closed 7 years ago.
I have to put a given variable into a regular expression. When I do it with hard coded data it works. Here is my code for that
/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!ccarn).)*$/
This should ( and does ) look for a word (password in this case) that is case sensitive, has at least one capitol and one lowercase letter, and one number or symbol. It cannot, however, contain the word "ccarn" in it. Again when I put this in as my regex all works out. When I try to turn it into a string that gets passed in, it doesn't work. Here is my code for that
var regex = new RegExp('/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$/');
I feel like I may just be missing something in translation/transition, but can't seem to get it right. TIA
When you use the new RegExp() constructor to construct a regex from a string, you shouldn't include the leading and trailing / within the string. The /.../ form is only to be used when specifying a regex literal, which isn't what you're doing here.
When you do, say, var r = new RegExp('/foo/'), the regex you're actually getting is equivalent to doing var r = /\/foo\//, which clearly isn't what you want. So your constructor should actually look like this:
var regex = new RegExp('^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$');
// ↑↑ ↑↑
// no "/" at the locations pointed to above
You probably also need to double your backslashes (since backslashes are escape characters in strings, but not in regex literals). So, [0-9##$-/:-?{-~!"^_`\[\]] needs to become [0-9##$-/:-?{-~!"^_`\\[\\]].
If you look closely the '/' character gets delimited when you give it inside the quotes so essentially the
var regex = new RegExp('/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$/');
The regular expression would be like this
/\/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-\/:-?{-~!"^_`[]])+((?!ccarn).)*$\//
The right way to go is to remove the '/' character from the RegEx and it should work
var regex = new RegExp('/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$/');
The output for the above would be
/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-\/:-?{-~!"^_`[]])+((?!ccarn).)*$/
which is exactly what you need ?
Hope it helps
Please before doing anything else, read a regex tutorial!
Mistakes:
A lookahead is a zero width assertion ( in other words, it's only a test and doesn't match anything ), putting a quantifier for a zero width assertion doesn't make any sense: (?=.*[a-z])+ (it is like repeating something empty, zero or more times. Note that the regex engine will protest if you write something like this.)
When you use the oop syntax to define a pattern (ie:var pattern = new RegExp("...), you don't need to add delimiters. You need to put double backslashes instead simple backslashes.

Firefox Extension How to pass string type variable into javascript replace regex parameter?

I've been working on firefox extension for several days now and there is one thing I can't solve.
I generate a list of regex and I wanted to pass that string into replace function in javascript (in the regex parameters). Here is the example of the string:
/(https?:\/\/(www\.)?rapidgator\.net\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))/g
/(https?:\/\/(www\.)?ul\.to\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))/g
/(https?:\/\/(www\.)?uploadable\.ch\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))/g
/(https?:\/\/(www\.)?180upload\.com\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))/g
For a convenient way, lets make it this way. I managed to get the file and get the first line of the string and assign it into a variable:
var rapidgator = "/(https?:\/\/(www\.)?rapidgator\.net\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))/g";
I want the string to be a "replace parameter" like this:
var rep = rep.replace(rapidgator,"<a href='$1'>$1</a>");
But I cant get that work.
I've been trying to use RegExp object and that didn't work to.
var rapidgator = new RegExp("(https?:\/\/(www\.)?rapidgator\.net\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))", "g");
How to make that work? Thank you for your advice :)
If you can get the regex, why not let it remain a regex literal?
var rapidgator = /(https?:\/\/(www\.)?rapidgator\.net\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))/g;
If you want to make it through RegExp constructor, make sure you escape \ with another backslash and you don't need delimiters and the second argument takes the flags.
As in
var rapidgator = new RegExp("(https?:\\/\\/(www\\.)?rapidgator\\.net\\b([-a-zA-Z0-9#:%_\+.~#?&//=]*))","g")
You need to escape the backslash one more time when passing your regex within double quotes.
var rapidgator = new RegExp("(https?://(www\\.)?rapidgator\\.net\\b([-a-zA-Z0-9#:%_\\\\+.~#?&/=]*))", "g");
And also to match a backslash, you need to escape it exactly three times.

javascript regex to require at least one special character

I've seen plenty of regex examples that will not allow any special characters. I need one that requires at least one special character.
I'm looking at a C# regex
var regexItem = new Regex("^[a-zA-Z0-9 ]*$");
Can this be converted to use with javascript? Do I need to escape any of the characters?
Based an example I have built this so far:
var regex = "^[a-zA-Z0-9 ]*$";
//Must have one special character
if (regex.exec(resetPassword)) {
isValid = false;
$('#vsResetPassword').append('Password must contain at least 1 special character.');
}
Can someone please identify my error, or guide me down a more efficient path? The error I'm currently getting is that regex has no 'exec' method
Your problem is that "^[a-zA-Z0-9 ]*$" is a string, and you need a regex:
var regex = /^[a-zA-Z0-9 ]*$/; // one way
var regex = new RegExp("^[a-zA-Z0-9 ]*$"); // another way
[more information]
Other than that, your code looks fine.
In javascript, regexs are formatted like this:
/^[a-zA-Z0-9 ]*$/
Note that there are no quotation marks and instead you use forward slashes at the beginning and end.
In javascript, you can create a regular expression object two ways.
1) You can use the constructor method with the RegExp object (note the different spelling than what you were using):
var regexItem = new RegExp("^[a-zA-Z0-9 ]*$");
2) You can use the literal syntax built into the language:
var regexItem = /^[a-zA-Z0-9 ]*$/;
The advantage of the second is that you only have to escape a forward slash, you don't have to worry about quotes. The advantage of the first is that you can programmatically construct a string from various parts and then pass it to the RegExp constructor.
Further, the optional flags for the regular expression are passed like this in the two forms:
var regexItem = new RegExp("^[A-Z0-9 ]*$", "i");
var regexItem = /^[A-Z0-9 ]*$/i;
In javascript, it seems to be a more common convention to the user /regex/ method that is built into the parser unless you are dynamically constructing a string or the flags.

Javascript regex expression to replace multiple strings?

I've a string done like this: "http://something.org/dom/My_happy_dog_%28is%29cool!"
How can I remove all the initial domain, the multiple underscore and the percentage stuff?
For now I'm just doing some multiple replace, like
str = str.replace("http://something.org/dom/","");
str = str.replace("_%28"," ");
and go on, but it's really ugly.. any help?
Thanks!
EDIT:
the exact input would be "My happy dog is cool!" so I would like to get rid of the initial address and remove the underscores and percentage and put the spaces in the right place!
The problem is that trying to put a regex on Chrome "something goes wrong". Is it a problem of Chrome or my regex?
I'd suggest:
var str = "http://something.org/dom/My_happy_dog_%28is%29cool!";
str.substring(str.lastIndexOf('/')+1).replace(/(_)|(%\d{2,})/g,' ');
JS Fiddle demo.
The reason I took this approach is that RegEx is fairly expensive, and is often tricky to fine tune to the point where edge-cases become less troublesome; so I opted to use simple string manipulation to reduce the RegEx work.
Effectively the above creates a substring of the given str variable, from the index point of the lastIndexOf('/') (which does exactly what you'd expect) and adding 1 to that so the substring is from the point after the / not before it.
The regex: (_) matches the underscores, the | just serves as an or operator and the (%\d{2,}) serves to match digit characters that occur twice in succession and follow a % sign.
The parentheses surrounding each part of the regex around the |, serve to identify matching groups, which are used to identify what parts should be replaced by the ' ' (single-space) string in the second of the arguments passed to replace().
References:
lastIndexOf().
replace().
substring().
You can use unescape to decode the percentages:
str = unescape("http://something.org/dom/My_happy_dog_%28is%29cool!")
str = str.replace("http://something.org/dom/","");
Maybe you could use a regular expression to pull out what you need, rather than getting rid of what you don't want. What is it you are trying to keep?
You can also chain them together as in:
str.replace("http://something.org/dom/", "").replace("something else", "");
You haven't defined the problem very exactly. To get rid of all stretches of characters ending in %<digit><digit> you'd say
var re = /.*%\d\d/g;
var str = str.replace(re, "");
ok, if you want to replace all that stuff I think that you would need something like this:
/(http:\/\/.*\.[a-z]{3}\/.*\/)|(\%[a-z0-9][a-z0-9])|_/g
test
var string = "http://something.org/dom/My_happy_dog_%28is%29cool!";
string = string.replace(/(http:\/\/.*\.[a-z]{3}\/.*\/)|(\%[a-z0-9][a-z0-9])|_/g,"");

How to put variable in regular expression match?

I have the following snippet. I want to find the appearance of a, but it does not work. How can I put the variable right?
var string1 = 'asdgghjajakhakhdsadsafdgawerwweadf';
var string2 = 'a';
string1.match('/' + string2 + '/g').length;
You need to use the RegExp constructor instead of a regex literal.
var string = 'asdgghjjkhkh';
var string2 = 'a';
var regex = new RegExp( string2, 'g' );
string.match(regex);
If you didn't need the global modifier, then you could just pass string2, and .match() will create the regex for you.
string.match( string2 );
If you are merely looking to check whether a string contains another string, then your best bet is simply to use match() without a regex.
You may object: But I need a regex to check for classes, like \s, to define complicated patterns, etc..
In that case: You will need change the syntax even more, double-escaping your classes and dropping starting/ending / regex indicator symbols.
Imagine this regex...
someString.match(/\bcool|tubular\b);
The exact equivalent of this, when using a new new RegExp(), is...
someStringRegex = new RegExp('\\bcool|tubular\\b');
Two things happened in this transition:
Drop the opening and closing / (otherwise, your regex will fail).
Double escape your character classes, like \b becomes \\b for word borders, and \w becomes \\w for whitespace, etc. (otherwise, your regex will fail).
Here is another example-
//confirm whether a string contains target at its end (both are variables in the function below, e.g. confirm whether str "Abstraction" contains target "action" at the end).
function confirmEnding(string, target) {
let regex = new RegExp(target);
return regex.test(string);
};

Categories