Case insensitive in regex with Javascript [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Case insensitive regex in javascript
Right now I have this:
my_list.match(new RegExp("(?:^|,)"+my_name+"(?:,|$)")))
Which, given the following:
my_list = "dog, cat, boy"
my_name = "dog"
Would return true.
However if I have
my_list = "Dog,Cat,boy"
and
my_name = "boy"
The regex wouldn't match. How would I adapt in order to be able to match with case insensitive?

First off: Never build a regular expression from an unescaped variable. Use this function to escape all special characters first:
RegExp.quote = function(str) {
return str.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&");
};
It modifies the RegExp object, you need to include it just once. Now:
function stringContains(str, token) {
var
spaces = /^\s+|\s+$/g, // matches leading/trailing space
token = token.replace(spaces, ""), // trim the token
re = new RegExp("(?:^|,)\\s*" + RegExp.quote(token) + "\\s*(?:,|$)", "i");
return re.test(str);
}
alert( stringContains("dog, cat, boy", " Dog ") );
Note
The "i" that makes the new RegExp case-insenstive.
The two added \s* that allow white-space before/after the comma.
The fact that "(?:^|,)\\s*" is correct, not "(?:^|,)\s*"" (in a JS string all backslashes need to be escaped).

Related

How to check if a string contains a WORD in javascript? [duplicate]

This question already has answers here:
How to check if a string contain specific words?
(11 answers)
Closed 3 years ago.
So, you can easily check if a string contains a particular substring using the .includes() method.
I'm interested in finding if a string contains a word.
For example, if I apply a search for "on" for the string, "phones are good", it should return false. And, it should return true for "keep it on the table".
You first need to convert it into array using split() and then use includes()
string.split(" ").includes("on")
Just need to pass whitespace " " to split() to get all words
This is called a regex - regular expression
You can use of 101regex website when you need to work around them (it helps). Words with custom separators aswell.
function checkWord(word, str) {
const allowedSeparator = '\\\s,;"\'|';
const regex = new RegExp(
`(^.*[${allowedSeparator}]${word}$)|(^${word}[${allowedSeparator}].*)|(^${word}$)|(^.*[${allowedSeparator}]${word}[${allowedSeparator}].*$)`,
// Case insensitive
'i',
);
return regex.test(str);
}
[
'phones are good',
'keep it on the table',
'on',
'keep iton the table',
'keep it on',
'on the table',
'the,table,is,on,the,desk',
'the,table,is,on|the,desk',
'the,table,is|the,desk',
].forEach((x) => {
console.log(`Check: ${x} : ${checkWord('on', x)}`);
});
Explaination :
I am creating here multiple capturing groups for each possibily :
(^.*\son$) on is the last word
(^on\s.*) on is the first word
(^on$) on is the only word
(^.*\son\s.*$) on is an in-between word
\s means a space or a new line
const regex = /(^.*\son$)|(^on\s.*)|(^on$)|(^.*\son\s.*$)/i;
console.log(regex.test('phones are good'));
console.log(regex.test('keep it on the table'));
console.log(regex.test('on'));
console.log(regex.test('keep iton the table'));
console.log(regex.test('keep it on'));
console.log(regex.test('on the table'));
You can .split() your string by spaces (\s+) into an array, and then use .includes() to check if the array of strings has your word within it:
const hasWord = (str, word) =>
str.split(/\s+/).includes(word);
console.log(hasWord("phones are good", "on"));
console.log(hasWord("keep it on the table", "on"));
If you are worried about punctuation, you can remove it first using .replace() (as shown in this answer) and then split():
const hasWord = (str, word) =>
str.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").split(/\s+/).includes(word);
console.log(hasWord("phones are good son!", "on"));
console.log(hasWord("keep it on, the table", "on"));
You can split and then try to find:
const str = 'keep it on the table';
const res = str.split(/[\s,\?\,\.!]+/).some(f=> f === 'on');
console.log(res);
In addition, some method is very efficient as it will return true if any predicate is true.
You can use .includes() and check for the word. To make sure it is a word and not part of another word, verify that the place you found it in is followed by a space, comma, period, etc and also has one of those before it.
A simple version could just be splitting on the whitespace and looking through the resulting array for the word:
"phones are good".split(" ").find(word => word === "on") // undefined
"keep it on the table".split(" ").find(word => word === "on") // "on"
This just splits by whitespace though, when you need parse text (depending on your input) you'll encounter more word delimiters than whitespace. In that case you could use a regex to account for these characters.
Something like:
"Phones are good, aren't they? They are. Yes!".split(/[\s,\?\,\.!]+/)
I would go with the following assumptions:
Words the start of a sentence always have a trailing space.
Words at the end of a sentence always have a preceding space.
Words in the middle of a sentence always have a trailing and preceding space.
Therefore, I would write my code as follows:
function containsWord(word, sentence) {
return (
sentence.startsWith(word.trim() + " ") ||
sentence.endsWith(" " + word.trim()) ||
sentence.includes(" " + word.trim() + " "));
}
console.log(containsWord("test", "This is a test of the containsWord function."));
Try the following -
var mainString = 'codehandbook'
var substr = /hand/
var found = substr.test(mainString)
if(found){
console.log('Substring found !!')
} else {
console.log('Substring not found !!')
}

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 regular expression for matching whole words including special characters

I am trying to match whole exact words using a javascript regular expression.
Given the strings: 1) "I know C++." and 2) "I know Java."
I have tried using new Regex('\\b' + text + '\\b', 'gi') and that works great for words without special characters like example #2.
I've also taken a look at this url:
Regular expression for matching exact word affect the special character matching
and implemented the:
escaped = escaped.replace(/^(\w)/, "\\b$1");
escaped = escaped.replace(/(\w)$/, "$1\\b");
and that will match text = 'C++' (it will match both examples)
However, if someone types a typo, and the string is "I know C++too.", the latter regex will still match the C++ when I don't want it to because the word "C++too" is not an exact match for text = 'C++'.
What changes can I make so that it will not match unless C++ is both the front of the word and the end of the word.
You can add a range of accepted characters([+#]) after word characters:
str = 'I know C++too. I know Java and C#.';
console.log(str.match(/(\w[+#]+|\w+)/g));
NB: \w[+#]+ must be placed first in the alternation expression to take precedence over the more generic \w+.
If whole words including special characters means everything but [\r\n\t\f\v ], you can simply do:
const REGEX = /([^\s]+)+/g;
function selectWords(string) {
const REGEX = /([^\s]+)+/g;
return string
// remove punctuation
.replace(/[^a-z0-9\s+#]/ig, "")
// perform the match
.match(REGEX)
// prevent null returns
|| []
;
}
var text = "Hello World"
var [first, second, ...rest] = selectWords(text);
console.log(1, {first, second, rest});
// example with punctuation
var text = "I can come today, she said, but not tomorrow."
var [first, second, third, ...rest] = selectWords(text);
console.log(2, {first, second, third, rest});
// example with possible throw
var text = ",.'\"` \r"
var [first, second, third, ...rest] = selectWords(text);
console.log(3, {first, second, third, rest});
// example with a specific word to be matched
function selectSpecificWord(string, ...words) {
return selectWords(string)
.filter(word => ~words.indexOf(word))
;
}
var expected = "C++";
var test = "I know C++";
var test1 = "I know C++AndJava";
console.log("Test Case 1", selectSpecificWord(test, expected));
console.log("Test Case 2", selectSpecificWord(test1, expected));
Use this ((?:(?:\w)+?)(?=\b|\w[-+]{2,2})(?:[-+]{2,2})?)
I've included a - symbol for an example also. See it in life.

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

Javascript Regexp: Replace curly braces [duplicate]

This question already has answers here:
regular expression does not work with javascript
(2 answers)
How do I replace all occurrences of a string in JavaScript?
(78 answers)
Closed 7 years ago.
Folks,
I'm trying to replace a huge chunk of string with a multiple occurrences of "${country_id}". I need a Regular expression that can replace the ${country_id}. Here is the code I have:
var iterLiteral = "\$\{"+literal+"\}"
var re = new RegExp(iterLiteral,"g")
var value = value;
return body.replace(re,value)
I get this error:
Evaluator: org.mozilla.javascript.EcmaError: Invalid quantifier }
How can I fix it?
Edit:
String to be replaced: ${country_id}
literal being passed to the function : country_id.
Trying to use what Anubhava said ( using \\ ), the program tries to search for \$\{country_id\} and it doesn't find one.
Edit 2: Why is this a duplicate? the question that was mentioned doesn't talk about escaping.
If you have a set regular expression, you might find it easier to use the // syntax for defining the RegExp:
'foo: ${country_id}, bar: ${country_id}'.replace(/\$\{country_id\}/g, 'baz')
Alternatively, if the string must be constructed, then you need to double escape the slashes for them to be a part of the regular expression, and not seen as escaping characters for the creation of the string itself:
'foo: ${country_id}, bar: ${country_id}'.replace(new RegExp('\\$\\{' + 'country_id' + '\\}', 'g'), 'baz')
Your function would thus be:
function replaceLiteral(body, literal, value) {
var iterLiteral = "\\$\\{" + literal + "\\}";
var re = new RegExp(iterLiteral, "g");
return body.replace(re, value)
}
var result = replaceLiteral('foo: ${country_id}, bar: ${country_id}', 'country_id', 'baz');
console.log(result);
All of these output the same string:
'foo: baz, bar: baz'
Using double slashes ought to work, if your .replace function is correct (meaning that you use the regex as the first argument, not the iterLiteral). If it doesn't, there's something going wrong else where in your code. If that's the case, please provide the whole function you are using.
function fandr(literal, value, el) {
var iterLiteral = "\\$\\{" + literal + "\\}",
re = new RegExp(iterLiteral, "g"),
$el = $(el);
console.log(re);
$el.html(function() {
return $el.html().replace(re, value);
});
}
fandr("country_id", "banana", "span");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>${country_id}</span>

Categories

Resources