The replace
function returns the new string with the replaces, but if there weren\'t any words to replace, then the original string is returned. Is there a way to k
Use .test()
const regex = /foo/;
const yourString = 'foo bar';
if (regex.test(yourString)) {
console.log('yourString contains regex');
}
The test() method executes a search for a match between a regular expression and a specified string. Returns true or false.
A simple option is to check for matches before you replace:
var regex = /i/g;
var newStr = str;
var replaced = str.search(regex) >= 0;
if(replaced){
newStr = newStr.replace(regex, '!');
}
If you don't want that either, you can abuse the replace
callback to achieve that in a single pass:
var replaced = false;
var newStr = str.replace(/i/g, function(token){replaced = true; return '!';});
With indexOf
you can check wether a string contains another string.
Seems like you might want to use that.
Javascript replace
is defected by design. Why? It has no compatibility with string replacement in callback.
For example:
"ab".replace(/(a)(b)/, "$1$2")
> "ab"
We want to verify that replace is done in single pass. I was imagine something like:
"ab".replace(/(a)(b)/, "$1$2", function replacing() { console.log('ok'); })
> "ab"
Real variant:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
return "$1$2";
})
> ok
> "$1$2"
But function replacing
is designed to receive $0, $1, $2, offset, string
and we have to fight with replacement "$1$2". The solution is:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
// arguments are $0, $1, ..., offset, string
return Array.from(arguments).slice(1, -2)
.reduce(function (pattern, match, index) {
// '$1' from strings like '$11 $12' shouldn't be replaced.
return pattern.replace(
new RegExp("\\$" + (index + 1) + "(?=[^\\d]|$)", "g"),
match
);
}, "$1$2");
});
> ok
> "ab"
This solution is not perfect. String replacement itself has its own WATs. For example:
"a".replace(/(a)/, "$01")
> "a"
"a".replace(/(a)/, "$001")
> "$001"
If you want to care about compatibility you have to read spec and implement all its craziness.
Comparing the before and after strings is the easiest way to check if it did anything, there's no intrinsic support in String.replace()
.
[contrived example of how '==' might fail deleted because it was wrong]
If your replace has a different length from the searched text, you can check the length of the string before and after. I know, this is a partial response, valid only on a subset of the problem.
OR
You can do a search. If the search is successfull you do a replace on the substring starting with the found index and then recompose the string. This could be slower because you are generating 3 strings instead of 2.
var test = "Hellllo";
var index = test.search(/ll/);
if (index >= 0) {
test = test.substr(0, index - 1) + test.substr(index).replace(/ll/g, "tt");
}
alert(test);