Javascript: String.match() - pass string variable in regular expression [duplicate] - javascript

This question already has answers here:
Javascript Regexp dynamic generation from variables? [duplicate]
(4 answers)
Closed 7 years ago.
I tried to rewrite the method (part of tutorial on w3schools).
The problem is to make a variable string to become part of the regular expression.
Tutorial Sample code:
function myFunction() {
var str = "The rain in SPAIN stays mainly in the plain";
var res = str.match(/ain/gi);
console.log(res)
}
I tried:
function myFunction() {
var str = "The rain in SPAIN stays mainly in the plain";
var test = "ain";
var re = "/"+test+"/gi";
var res = str.match(re);
console.log(res);
}
The way I tried did not work.

Use the regex constructor, like:
function myFunction() {
var str = "The rain in SPAIN stays mainly in the plain",
test = "ain",
re = new RegExp(test, 'gi'),
res = str.match(re);
console.log(res);
}

You need to use RegExp constructor if you want to pass a value of variable as regex.
var test = "ain";
var re = new RegExp(test, "gi");
If your variable contains special chars, it's better to escape those.
var re = new RegExp(test.replace(/(\W)/g, "\\$1"), "gi");

Note that you pass a string to match. If we follow the documentation, this will do a new RegExp(test). So you should avoid / and /gi strings and add corresponding flags to the RegExp constructor: the default constructor doesn't add neither global search (g) nor case insensitive search (i).
So the solution to your problem:
var str = "The rain in SPAIN stays mainly in the plain";
var test = "ain";
var res = str.match(new RegExp(test, "gi"));
This will returns :
Array [ "ain", "AIN", "ain", "ain" ]
Note :
The form str.match(test, "gi"); works only in Firefox browser but is deprecated and throws a console warning from Firefox 39 (see RGraham comment).

Yes match() not works with string literals
You can use var re = new RegExp(test,"gi");
var str = "The rain in SPAIN stays mainly in the plain";
var test = "ain";
var re = new RegExp(test,"gi");
var res = str.match(re);
console.log(res);

You could have searched for "dynamic regular expressions" and you would have found:
Javascript Regexp dynamic generation from variables?
or Use dynamic (variable) string as regex pattern in JavaScript which both describe it very well.

Related

JS Regex match word, but the word is dynamic [duplicate]

This question already has answers here:
How do you use a variable in a regular expression?
(27 answers)
Closed 2 years ago.
So for example:
function(input){
var testVar = input;
string = ...
string.replace(/ReGeX + testVar + ReGeX/, "replacement")
}
But this is of course not working :)
Is there any way to do this?
const regex = new RegExp(`ReGeX${testVar}ReGeX`);
...
string.replace(regex, "replacement");
Update
Per some of the comments, it's important to note that you may want to escape the variable if there is potential for malicious content (e.g. the variable comes from user input)
ES6 Update
In 2019, this would usually be written using a template string, and the above code has been updated. The original answer was:
var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");
You can use the RegExp object:
var regexstring = "whatever";
var regexp = new RegExp(regexstring, "gi");
var str = "whateverTest";
var str2 = str.replace(regexp, "other");
document.write(str2);
Then you can construct regexstring in any way you want.
You can read more about it here.
To build a regular expression from a variable in JavaScript, you'll need to use the RegExp constructor with a string parameter.
function reg(input) {
var flags;
//could be any combination of 'g', 'i', and 'm'
flags = 'g';
return new RegExp('ReGeX' + input + 'ReGeX', flags);
}
of course, this is a very naive example. It assumes that input is has been properly escaped for a regular expression. If you're dealing with user-input, or simply want to make it more convenient to match special characters, you'll need to escape special characters:
function regexEscape(str) {
return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
}
function reg(input) {
var flags;
//could be any combination of 'g', 'i', and 'm'
flags = 'g';
input = regexEscape(input);
return new RegExp('ReGeX' + input + 'ReGeX', flags);
}
You can create regular expressions in JS in one of two ways:
Using regular expression literal - /ab{2}/g
Using the regular expression constructor - new RegExp("ab{2}", "g") .
Regular expression literals are constant, and can not be used with variables. This could be achieved using the constructor. The stracture of the RegEx constructor is
new RegExp(regularExpressionString, modifiersString)
You can embed variables as part of the regularExpressionString. For example,
var pattern="cd"
var repeats=3
new RegExp(`${pattern}{${repeats}}`, "g")
This will match any appearance of the pattern cdcdcd.
if you're using es6 template literals are an option...
string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")
You can always give regular expression as string, i.e. "ReGeX" + testVar + "ReGeX". You'll possibly have to escape some characters inside your string (e.g., double quote), but for most cases it's equivalent.
You can also use RegExp constructor to pass flags in (see the docs).
It's only necessary to prepare the string variable first and then convert it to the RegEx.
for example:
You want to add minLength and MaxLength with the variable to RegEx:
function getRegEx() {
const minLength = "5"; // for exapmle: min is 5
const maxLength = "12"; // for exapmle: man is 12
var regEx = "^.{" + minLength + ","+ maxLength +"}$"; // first we make a String variable of our RegEx
regEx = new RegExp(regEx, "g"); // now we convert it to RegEx
return regEx; // In the end, we return the RegEx
}
now if you change value of MaxLength or MinLength, It will change in all RegExs.
Hope to be useful. Also sorry about my English.
Here's an pretty useless function that return values wrapped by specific characters. :)
jsfiddle: https://jsfiddle.net/squadjot/43agwo6x/
function getValsWrappedIn(str,c1,c2){
var rg = new RegExp("(?<=\\"+c1+")(.*?)(?=\\"+c2+")","g");
return str.match(rg);
}
var exampleStr = "Something (5) or some time (19) or maybe a (thingy)";
var results = getValsWrappedIn(exampleStr,"(",")")
// Will return array ["5","19","thingy"]
console.log(results)
accepted answer doesn't work for me and doesn't follow MDN examples
see the 'Description' section in above link
I'd go with the following it's working for me:
let stringThatIsGoingToChange = 'findMe';
let flagsYouWant = 'gi' //simple string with flags
let dynamicRegExp = new RegExp(`${stringThatIsGoingToChange}`, flagsYouWant)
// that makes dynamicRegExp = /findMe/gi

Javascript regex error " /?/: nothing to repeat " It worked fine earlier [duplicate]

This question already has answers here:
What does the "Nothing to repeat" error mean when using a regex in javascript?
(7 answers)
Closed 4 years ago.
I'm trying to clear a string of any invalid characters to be set as a directory.
Tried a number of methods and this one eventually worked[custom encoding] but now it doesn't, it says "nothing to repeat" in the console. What does that mean? using Chrome.
Here's the code(using random string):
var someTitle = "wa?";
var cleanTitle = cleanTitle(someTitle);
function cleanTitle(title){
var obstructions = ['\\','/',':','*','?','"','<','>','|'];
var solutions = [92,47,58,42,63,34,60,62,124];
var encodedTitle = title;
for (var obstruction = 0; obstruction < obstructions.length; obstruction++){
var char = obstructions[obstruction];
if (encodedTitle.includes(char)){
var enCode = "__i!__"+solutions[obstruction]+"__!i__";
var rEx = new RegExp(char,"g");
encodedTitle = encodedTitle.replace(rEx,enCode);
}
}
console.log("CLEAN: "+title);
console.log("ENCODED: "+encodedTitle);
return encodedTitle;
}
Heres the error:
Uncaught SyntaxError: Invalid regular expression: /?/: Nothing to
repeat
It points to this line -> var rEx = new RegExp(char,"g");
You need to escape some characters when using them as literals in a regular expression. Among those are most of the characters you have in your array.
Given your function replaces the obstruction characters with their ASCII code (and some wrapping __i!__), I would suggest to make your function a bit more concise, by performing the replacement with one regular expression, and a callback passed to .replace():
function cleanTitle(title){
return title.replace(/[\\/:*?"<>|]/g, function (ch) {
return "__i!__"+ch.charCodeAt(0)+"__!i__";
});
}
var someTitle = "wh*r* is |his?";
var result = cleanTitle(someTitle);
console.log(result);
...and if you are in an ES6 compatible environment:
var cleanTitle = t=>t.replace(/[\\/:*?"<>|]/g, c=>"__i!__"+c.charCodeAt(0)+"__!i__");
var someTitle = "wh*r* is |his?";
var result = cleanTitle(someTitle);
console.log(result);
The ? is a regex modifier. When you want to look for it (and build a regex with it), you need to escape it.
That beeing said, a harmless unuseful escaping doesn't hurt (or makes your other search params useable, as there are many modifiers or reserved chars in it) your other search params. So go with
var char = '\\' + obstructions[obstruction];
to replace them all with a (for the regex) string representation
/?/ is not a valid regex. For it to be a regex, you need /\?/.
Regex here would be awkward, as most of the characters need escaping. Instead, consider using a literal string replacement until it is no longer found:
while( encodedTitle.indexOf(char) > -1) {
encodedTitle = encodedTitle.replace(char,enCode);
}

Passing Parameter into function match

I am using the function match for a search engine, so whenever a user types a search-string I take that string and use the match function on an array containing country names, but it doesn't seem to work.
For example if I do :
var string = "algeria";
var res = string.match(/alge/g); //alge is what the user would have typed in the search bar
alert(res);
I get a string res = "alge": //thus verifying that alge exists in algeria
But if I do this, it returns null, why? and how can I make it work?
var regex = "/alge/g";
var string = "algeria";
var res = string.match(regex);
alert(res);
To make a regex from a string, you need to create a RegExp object:
var regex = new RegExp("alge", "g");
(Beware that unless your users will be typing actual regular expressions, you'll need to escape any characters that have special meaning within regular expressions - see Is there a RegExp.escape function in Javascript? for ways to do this.)
You don't need quotes around the regex:
var regex = /alge/g;
Remove the quotes around the regex.
var regex = /alge/g;
var string = "algeria";
var res = string.match(regex);
alert(res);
found the answer, the match function takes a regex object so have to do
var regex = new RegExp(string, "g");
var res = text.match(regex);
This works fine

Javascript Regex: How to put a variable inside a regular expression? [duplicate]

This question already has answers here:
How do you use a variable in a regular expression?
(27 answers)
Closed 2 years ago.
So for example:
function(input){
var testVar = input;
string = ...
string.replace(/ReGeX + testVar + ReGeX/, "replacement")
}
But this is of course not working :)
Is there any way to do this?
const regex = new RegExp(`ReGeX${testVar}ReGeX`);
...
string.replace(regex, "replacement");
Update
Per some of the comments, it's important to note that you may want to escape the variable if there is potential for malicious content (e.g. the variable comes from user input)
ES6 Update
In 2019, this would usually be written using a template string, and the above code has been updated. The original answer was:
var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");
You can use the RegExp object:
var regexstring = "whatever";
var regexp = new RegExp(regexstring, "gi");
var str = "whateverTest";
var str2 = str.replace(regexp, "other");
document.write(str2);
Then you can construct regexstring in any way you want.
You can read more about it here.
To build a regular expression from a variable in JavaScript, you'll need to use the RegExp constructor with a string parameter.
function reg(input) {
var flags;
//could be any combination of 'g', 'i', and 'm'
flags = 'g';
return new RegExp('ReGeX' + input + 'ReGeX', flags);
}
of course, this is a very naive example. It assumes that input is has been properly escaped for a regular expression. If you're dealing with user-input, or simply want to make it more convenient to match special characters, you'll need to escape special characters:
function regexEscape(str) {
return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
}
function reg(input) {
var flags;
//could be any combination of 'g', 'i', and 'm'
flags = 'g';
input = regexEscape(input);
return new RegExp('ReGeX' + input + 'ReGeX', flags);
}
You can create regular expressions in JS in one of two ways:
Using regular expression literal - /ab{2}/g
Using the regular expression constructor - new RegExp("ab{2}", "g") .
Regular expression literals are constant, and can not be used with variables. This could be achieved using the constructor. The stracture of the RegEx constructor is
new RegExp(regularExpressionString, modifiersString)
You can embed variables as part of the regularExpressionString. For example,
var pattern="cd"
var repeats=3
new RegExp(`${pattern}{${repeats}}`, "g")
This will match any appearance of the pattern cdcdcd.
if you're using es6 template literals are an option...
string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")
You can always give regular expression as string, i.e. "ReGeX" + testVar + "ReGeX". You'll possibly have to escape some characters inside your string (e.g., double quote), but for most cases it's equivalent.
You can also use RegExp constructor to pass flags in (see the docs).
It's only necessary to prepare the string variable first and then convert it to the RegEx.
for example:
You want to add minLength and MaxLength with the variable to RegEx:
function getRegEx() {
const minLength = "5"; // for exapmle: min is 5
const maxLength = "12"; // for exapmle: man is 12
var regEx = "^.{" + minLength + ","+ maxLength +"}$"; // first we make a String variable of our RegEx
regEx = new RegExp(regEx, "g"); // now we convert it to RegEx
return regEx; // In the end, we return the RegEx
}
now if you change value of MaxLength or MinLength, It will change in all RegExs.
Hope to be useful. Also sorry about my English.
Here's an pretty useless function that return values wrapped by specific characters. :)
jsfiddle: https://jsfiddle.net/squadjot/43agwo6x/
function getValsWrappedIn(str,c1,c2){
var rg = new RegExp("(?<=\\"+c1+")(.*?)(?=\\"+c2+")","g");
return str.match(rg);
}
var exampleStr = "Something (5) or some time (19) or maybe a (thingy)";
var results = getValsWrappedIn(exampleStr,"(",")")
// Will return array ["5","19","thingy"]
console.log(results)
accepted answer doesn't work for me and doesn't follow MDN examples
see the 'Description' section in above link
I'd go with the following it's working for me:
let stringThatIsGoingToChange = 'findMe';
let flagsYouWant = 'gi' //simple string with flags
let dynamicRegExp = new RegExp(`${stringThatIsGoingToChange}`, flagsYouWant)
// that makes dynamicRegExp = /findMe/gi

RegExp to match words wrapped in braces

In javascript, I've got a block of HTML like this:
<h2>{title}</h2>
<p>{content}</p>
And I'm trying use regex "match" to spit out an array of all the {item}'s. So my output should look like:
['title', 'url', 'content']
I've gotten as far as:
var pattern = new RegExp("\{[a-zA-Z]+\}+");
var match = pattern.exec("{Sample} bob {text}");
But it's only returning the first tag.
This is just beyond my regex skills. Can anyone help?
Cheers!
You need to create a pattern with the global flag:
var pattern = new RegExp("\{[a-zA-Z]+\}", "g");
or:
var pattern = /\{[a-zA-Z]+\}/g;
Then you can call the match() method on your string to get a list of matches:
var matches = "{Sample} bob {text}".match(pattern);
I think you want:
var pattern = new RegExp("\{[a-zA-Z]+\}+", "g");
The second option is a flag telling it to search the entire string and return all matches.
See: http://www.evolt.org/article/Regular_Expressions_in_JavaScript/17/36435/ for more details.
Have you tried this yet?
<script>
var text = '<h2>{title}</h2>\n<p>{content}</p>';
var regex = /\{[a-z]+\}/ig;
var result = text.match(regex);
for (var i = 0; i < result.length; i++) {
console.debug(i + ". " + result[i]);
}
/*
gives:
0. {title}
1. {test}
2. {url}
3. {content}
*/
</script>
Much as I like to roll my own RegExp (and you really just need the global flag), have you looked at prototype templates, Trimpath JST or anything like that?
Because possibly rolling your own won't be as efficient for reuse as the above examples. EG:
String.prototype.template = function (obj) {
return this.replace(/{([^{}]+)}/g,
function (full, word) {
return((typeof obj[word]==='string'||typeof obj[word]==='number')?obj[word]:full);
}
);
};
"The {adj1} {adj2} {noun}.".template({adj1: 'lazy',adj2: 'brown', noun: 'dog'})
==> "The lazy brown dog."
This runs your regex each time, while I believe the prototype templates basically does it once.
I got off path by using exec for testing.

Categories

Resources