Use regular expression with Javascript RegExp constructor - javascript

I have a regular expression like this and it works fine using https://regexr.com/
([a-zA-Z0-9-.~%!$&'()*+,;=#]+(/[a-zA-Z0-9-.~%!$&'()+,;=:#]+)/?|(/[a-zA-Z0-9-.~%!$&'()*+,;=:#]+)+/?)(?[a-zA-Z0-9-.~%!$&'()+,;=:#/?])?(#[a-zA-Z0-9-._~%!$&'()+,;=:#/?])?
I would like to use it with RegExp() like below(I just put the above string inside the raw string), but it does not work. Do I need to do any other treatment?
const pattern =String.raw`([a-zA-Z0-9\-._~%!$&'()*+,;=#]+(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)*\/?|(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)+\/?)(\?[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?(\#[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?`;
let re = new RegExp(pattern);
return re.test(somestring)
I also tried enclose the regex with / and / like below and it does not work either. It allows spaces but I don't really allow space.
const re = new RegExp(/([a-zA-Z0-9\-._~%!$&'()*+,;=#]+(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)*\/?|(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)+\/?)(\?[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?(\#[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?/);
Updates:
I guess my question should be how do I make sure it matches full text like what I can do test in the website above(attached screenshot below)

I think the root of this question is that regexr is matching on the full string rather than just a part. .test() will return true if part of the regex matches. if you want to only return true when matching the on the full string I would suggest using start ^ and end $ delimiters.
const pattern =String.raw`^([a-zA-Z0-9\-._~%!$&'()*+,;=#]+(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)*\/?|(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)+\/?)(\?[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?(\#[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?$`;
let re = new RegExp(pattern);
console.log(re.test('asdf```'))

Match the beginning ^ and end $ of a string to get an exact match, otherwise a substring will be accepted.
const re = new RegExp('^regex$')
On the sample string:
const reStr = `^([a-zA-Z0-9\-._~%!$&'()*+,;=#]+(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)*\/?|(\/[a-zA-Z0-9\-._~%!$&'()*+,;=:#]+)+\/?)(\?[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?(\#[a-zA-Z0-9\-._~%!$&'()*+,;=:#/?]*)?$`

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);

How to set variable-template in the regular expression?

There is a file extension pattern:
const pattern = '.js';
How correctly to set a template, to make regex work?
const reg = /(.*\pattern$)/;
Use the regex constructor. Link to docs.
For your snippet:
const pattern = '.js';
const reg = new RegExp(`(.*${pattern}$)`);
This has the caveat that you have to double escape your backslashes (the first one escapes it in the string, so that the second actually makes it into the regex). I'm assuming the one present in the example was a part of your attempt to put the pattern in there, but if not then it should be
new RegExp(`(.*\\${pattern}$)`)

Javascript regular expression: save matching value

I have the following expression in JS (typescript, but I think everyone understands what it transpiles to):
markString(text: string) {
const regEx = new RegExp(this.partToHighlight, 'ig');
return text.replace(regEx, `<mark>${this.partToHighlight}<\/mark>`);
}
The problem is that this way, with the 'ig'-option, the matching value can have any case, upper or lower, but is always replaced by the partToHighlight-value. Instead the function should read the matched value, save it and output it surrounded with the HTML-tags. How do I do this? I am pretty sure this is a duplicate question, but I couldn't find the one asked before.
You need to replace with the found match, $&:
markString(text: string) {
const regEx = new RegExp(this.partToHighlight, 'ig');
return text.replace(regEx, "<mark>$&</mark>");
}
Using $&, you replace with found match with the the same text found and do not need to hardcode the replacement, nor use any callbacks.
See "Specifying a string as a parameter" for more details.
As mentionned in comments you will need to use RegExp.lastMatch or $&, to point out to the matched substring, in your replace() method:
const regEx = new RegExp(this.partToHighlight, 'ig');
return text.replace(regEx, `<mark>$&<\/mark>`);

How can I inverse matched result of the pattern?

Here is my string:
Organization 2
info#something.org.au more#something.com market#gmail.com single#noidea.com
Organization 3
headmistress#money.com head#skull.com
Also this is my pattern:
/^.*?#[^ ]+|^.*$/gm
As you see in the demo, the pattern matches this:
Organization 2
info#something.org.au
Organization 3
headmistress#money.com
My question: How can I make it inverse? I mean I want to match this:
more#something.com market#gmail.com single#noidea.com
head#skull.com
How can I do that? Actually I can write a new (and completely different) pattern to grab expected result, but I want to know, Is "inverting the result of a pattern" possible?
No, I don't believe there is a way to directly inverse a Regular Expression but keeping it the same otherwise.
However, you could achieve something close to what you're after by using your existing RegExp to replace its matches with an empty string:
var everythingThatDidntMatchStr = str.replace(/^.*?#[^ ]+|^.*$/gm, '');
You can replace the matches from first RegExp by using Array.prototype.forEach() to replace matched RegExp with empty string using `String.ptototype.replace();
var re = str.match(/^.*?#[^ ]+|^.*$/gm);
var res = str;
re.forEach(val => res = res.replace(new RegExp(val), ""));

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.

Categories