Replacing only exact matches in Regex [duplicate] - javascript

This question already has answers here:
How can I match a whole word in JavaScript?
(4 answers)
Closed 4 months ago.
I have a javascript function that replaces strings that match against a profanity library with symbols.
eg. damn is transformed into ##$%&!
However, this replace is non-discriminating, and will transform partial matches as well.
eg. classic is transformed into cl##$%&!ic
I'm very new to TS/JS and Regex and would like some help understanding this function's arguments and how to modify them for only exact matches.
this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, "\\$&"), (ignore ? "gi" : "g")), (typeof (str2) == "string") ? str2.replace(/\$/g, "$$$$") : str2);

To avoid partial matches, the normal solution is to surround what you want to match with word boundaries \b.
The following example assumes that profanities does not contain any words that contain regex special characters.
Notice that the "shit" in "mishit" and the "ass" in "class" do not get replaced.
const profanities = ['damn', 'shit', 'ass'];
// As regex literal: /\b(?:damn|shit|ass)\b/
const re = new RegExp('\\b(?:' + profanities.join('|') + ')\\b', 'gi');
const text = "Damn, another mishit. I am shit at pool. Time to get my ass to class.";
console.log(text.replace(re, '##$%&!'));

Related

Re-replacing in regex [duplicate]

This question already has answers here:
Regex matching 5-digit substrings not enclosed with digits
(2 answers)
Closed 2 years ago.
I am creating a function that replaces the string with a
~(number)~.
Now let's say I have a string that says
This is the replacement of ~26~ and ~524~. We still have 2 cadets left. Have2go for the next mission.2
I want to replace all the 2 in a string with ~86~ but when I am doing so the 2 in ~26~ and ~524~ also getting replaced to ~~86~6~ and ```~5~86~4~.
function replaceGameCoordinate() {
var string = `This is the replacement of ~26~ and ~524~. We still have 2 cadets left. Have2go for the next mission.2`
var replaceArr = ['2'];
let patt = new RegExp(`${replaceArr[0]}`, 'gm')
var newString = string.replace(patt, "~86~");
console.log(newString);
}
replaceGameCoordinate();
The expected output should be :
This is the replacement of ~26~ and ~524~. We still have ~86~ cadets left. Have~86~go for the next mission.~86~
So you need a different regex rule. You don't want to replace 2. You want to replace 2 when it's not next to another number or ~.
In order to do this, you can use lookaheads and lookbehinds (although lookbehinds are not yet supported by regexes in JS, I believe, but at least with lookaheads) :
const input = "This is the replacement of ~26~ and ~524~. We still have 2 cadets left. Have2go for the next mission.2";
const regex = /2(?![\d~])/gm // Means : "2 when it's not followed by a digit \d or a ~"
console.log( input.replace(regex, "~86~" ) )

RegExp vs /.../ [duplicate]

This question already has answers here:
JavaScript: RegExp constructor vs RegEx literal
(4 answers)
Closed 4 years ago.
I am trying to learn regular expressions in Javascript through this brilliant book "Eloquent Javascript" by Marijn Haverbeke. I am unable to figure out why some of these match and why some don't even though they seem fine. I don't know if I have misunderstood something or understood something partially. For example -
console.log(/'\d+'/.test("123"));
// This doesn't match
console.log(/'\d+'/.test("'123'"));
// This matches
let myRegEx = new RegExp("\d+");
console.log(myRegEx.test("123"));
//Doesn't match
console.log(myRegEx.test("'123'"));
//Doesn't match either
Also, why are '' required inside "" for the string to be matched?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
The correct code:
console.log(/\d+/.test("123"));
or
let myRegEx = new RegExp("\\d+");
console.log(myRegEx.test("123"));
You have to add \ for the new RegExpr because "\\d+" is a string interpreted as "\d+"
Also, why are '' required inside "" for the string to be matched?
They are not:
/\d+/ matches "A number, one or more that one time"
/'\d+'/ matches "A quote, then A number, one or more that one time, then a quote"
So:
/\d+/.test("123") === true
/'\d+'/.test("123") === false (because ' are not found)
/\d+/.test("'123'") === true (because numbers are found)
/'\d+'/.test("'123'") === true
\ is an escape character in string literals as well as regular expressions.
"\d+" is the same as "d+" so you are testing for 1 or more instances of the character d.

javascript - Regex make string uppercase [duplicate]

This question already has answers here:
Replace a Regex capture group with uppercase in Javascript
(7 answers)
Closed 5 years ago.
I wonder if there is a way to make a string uppercase using regex only in JS.
The thing is that I am giving my users a string transformation system.
The user supply me with three parameters : original text, replace regex, subtitution regex.
for example:
original : 'stackoverflow'
replace : /([a-z])(.*)/g
subtitution : $1
Result : 's'
I want to give them the abilitty to set the entire string to uppercase. I've noticed in some other SO questions that there are systems that allows that. for example in sublime text you can do '/\U$1/' to set the entire string to uppercase.
Notice: I cannot use toUpperCase or toLowerCase in any way
Javascript has an inbuilt uppercasing method
var str = "Hello World!";
var res = str.toUpperCase();
The result of res will be:
HELLO WORLD!

Tricky RegEx Capture [duplicate]

This question already has answers here:
My regex is matching too much. How do I make it stop? [duplicate]
(5 answers)
Closed 6 years ago.
I've got a couple strings and I need to pull characters out that appear between double quotes. The problem is, I want to grab them in groups.
var str = 'FF\"J"A4"L"';
var results = str.match(/\"(.*)\"/);
This returns everything between the first and last double quote. In this case it returns J"A4"L but what I need it to return is J and L.
The content between quotes is pretty much any unicode character like letters and numbers including as }, =, and #.
Any ideas on how to complete this with regex?
It sounds like the content between quotes is any character except for a quote, in which case you can get away with
/"([^"]*)"/
what you're looking for is this with the /g "global flag":
/("[^"]*")/g
In your example, it's like this:
var str = 'FF\"J"A4"L"';
var results = str.match(/("[^"]*")/g);
When doing this, results would be [""J"", ""L""], which contains the entire match (which is why the extra quotes are there).
If you wanted just the matched groups (which returns just the groups, not the whole match area), you would use exec:
var str = 'FF\"J"A4"L"';
var results = []
var r = /("[^"]*")/g
match = r.exec(str);
while (match != null) {
results.push(match[1])
match = r.exec(str);
}
Now, results is ["J", "L"]

RegEx is not working with backslash in javascript [duplicate]

This question already has answers here:
Why does a RegExp with global flag give wrong results?
(7 answers)
Closed 7 years ago.
I am trying to validate strings with following pattern.
starts with 3 digits followed by hyphen followed by 2 digits and ends with 4 digits.
eg : 123-45-6789
I need to pass the pattern to a RegExp object as a string variable (I am getting the pattern value from a html element attribute ), hence I have escaped the RegExp with double slashes. To my surprise, I am seeing weird results.
var pattern = "^\\d{3}-\\d{2}-\\d{4}$";
var inputRegex = new RegExp(pattern, "g");
console.log(inputRegex.test('132-45-7899')); //True
console.log(inputRegex.test('132-45-7899')); //False
console.log(inputRegex.test('132-45-7899')); //True
console.log(inputRegex.test('132-45-7899')); //False
What am I doing wrong here? and what is the reason for this inconsistent results?
EDIT:
Now I understood why the results are inconsistent , but my actual problem remained unsolved.
HTML elem is like below
SCENARIO 1:
<input data-val-regexp="^\\d{3}-\\d{2}-\\d{4}$" id="ticketNumber">
var regexPattern = input.attr("data-val-regexp");
var inputRegex = new RegExp(regexPattern);
return inputRegex.test('123-45-6789'); // False
When I inspected, the inputRegex.source is "^\\d{3}-\\d{2}-\\d{4}$"
SCENARIO 2:
If I assign the regexPattern with string literals everything works fine.
var pattern = "^\\d{3}-\\d{2}-\\d{4}$";
var inputRegex = new RegExp(pattern);
console.log(inputRegex.test('132-45-7899')); //True
In the above case inputRegex source value is "^\d{3}-\d{2}-\d{4}$"
Why is the backslash escaped in the second scenario, where as it didn't in the first scenario? What needs to be done in order to make scenario 1 work?
Because you're creating the regular expression with the g flag, it remembers where it left off and starts matching there, instead of at the beginning, the next time you call test. See Why does Javascript's regex.exec() not always return the same value?.

Categories

Resources