I found a bug in my JavaScript code that I have isolated to a string replace that is acting in a way I didn't expect. Here is an example of the code:
var text = "as";
text = text.replace(text,"$\'");
console.log(text);
This prints an empty string to the console. I was expecting it to print $' to the console. Can anyone explain this?
In order to use $ in resulting string, use $$ as $ has special meaning in JavaScript Regular Expressions and String replace method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter
If I don't know what is in my replacement string I use
replaceWith = "might have 2 $ signs $$ $$$ $$$$"
"a b c".replace("b", replaceWith) // unexpected result
"a b c".replace("b", function(){return replaceWith}) // no surprises
Actually, the most straight forward answer to this question is to use a function for the replacement string, because the w3c spec states that this result will not be affected by special characters.
var str = "abc {def} ghi";
console.log(str.replace("{def}", function() {
return "foo$'bar";
}));
// result is
// "abc foo$'bar ghi"
The MDN documentation for that is here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
Related
This question already has answers here:
Is there a RegExp.escape function in JavaScript?
(18 answers)
Closed 3 years ago.
I have this Example 1:
myString = 'cdn.google.com/something.png';
console.log(myString.match(myString));
Everything works just fine, but when it comes to Example 2:
myString = 'cdn.google.com/something.png?231564';
console.log(myString.match(myString));
It returns the value of 'null'. I don't know what happened anymore.. I searched for the keywords 'a string does not Match itself' and found nothing. Can somebody help me? Thank you.
The String#match method would treat the argument as a regex(by parsing if not), where . and ? has special meaning.
. matches any character (except for line terminators)
? Quantifier — Matches between zero and one times, as many times as possible, giving back as needed
So . wouldn't cause any problem since . can be used to match any character except line but ? would since it's using to match zero or one-time occurrence of any character.
For eg: .png?23 => matches .png23 or .pn23
From MDN docs :
If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).
It's better to use String#indexOf instead which returns the index in the string if found or returns -1 if not found.
console.log(myString.indexOf(myString) > -1);
match in Javascript compares a String against a RegEx. Luckily in your first example it works.
I guess you are looking for a method like localCompare.
Hope this helps!
match() search the string using a regular expression pattern.
So
var s = "My String";
s.match(/Regex Here/);
will try to match s for given regular expression .
In your example:-
myString = 'cdn.google.com/something.png'; // It will be treated as regex
console.log(myString.match(myString));
myString = 'cdn.google.com/something.png?231564'; // It will be treated as regex , result differ because of ?
console.log(myString.match(myString));
You can escape the argument to match, however if you do that you could just use == to compare the strings. This post contains a regex string escape function:
How to escape regular expression in javascript?
RegExp.quote = function(str) {
return (str+'').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&");
};
It can be used like this:
myString = 'cdn.google.com/something.png?231564';
console.log(myString.match(RegExp.quote
(myString)));
If you want to match any number after the question mark, you could do it like this:
myString = 'cdn.google.com/something.png?';
console.log((myString+"18193819").match(RegExp.quote
(myString) + '\\d+'));
I'm not using JQuery, so I don't think that's causing the trouble. I first ran into this using the iOS automation tool and then went to verify it using JSFiddle. If anyone can show me a way around this it would fantastic.
var str = "<'pass!23$'>";
var str1 = str.replace("<'pass!23$'>", "'pass!23$'");
var str2 = str.replace("<'pass!23$'>", "'pass!23$a'");
Here's the fiddle: http://jsfiddle.net/adUtw/
This is really confusing me!
If you look at the documentation for string.replace at MDN, you'll notice that $ alone has some special meanings for replace. Therefore, if you want to insert a $ you need to use $$.
Your replace statement would then look like:
var str1 = str.replace("<'pass!23$'>", "'pass!23$$'");
You can verify it is working by updating the Fiddle.
$ is interpreted in a special way when it appears in the second argument to replace.
It is used to refer to regex groups defined in the first argument:
'abc'.replace('(b)', 'XY$1Z') === 'aXYbZc'
And $' is interpreted as the portion of the string that follows the matched substring.
To use a $ in the second argument, escape it by saying $$.
var str1 = str.replace("<'pass!23$'>", "'pass!23$$'");
Does anyone see why the first three searches in the jsfiddle here - http://jsfiddle.net/tJ9uQ/ return -1?
Thanks
var gotoTarget = "http://register.php?from=";
var off1 = gotoTarget.search('register.php?from=');
console.log ("off1="+off1);
off2 = gotoTarget.search('register.php\?from=');
console.log ("off2="+off2);
off3 = gotoTarget.search('register.phpfrom=');
console.log ("off3="+off3);
off4 = gotoTarget.search('register.php');
console.log ("off4="+off4);
The parameter passed to .search() is a regular expression. If a regular expression is not passed, what is passed is implicitly converted to a regular expression.
Per the MDN Docs:
str.search(regexp)
Parameters
A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).
You need to escape the question mark, as the question mark is a valid regex character.
var off1 = gotoTarget.search('register\\.php\\?from=');
console.log(off1); // returns 7
In your examples above, the first one is not escaped at all, the second is incorrectly escaped and third is missing the ? so no match will be found.
Fiddle
This question already has answers here:
Javascript string replace weirdness -- $$$$ gets collapsed to $$ -- what's the reason behind this result? [duplicate]
(3 answers)
`string.replace` weird behavior when using dollar sign ($) as replacement
(3 answers)
Closed 4 years ago.
I am trying to replace "this" in the below example with "$$Ashok".I am not getting expected output.
var adHtmltext ="this is ashok"
adHtmltext = adHtmltext.replace("this", "$$Ashok");
alert(adHtmltext );
why it is showing one $ in output? how to fix this?
Here is the jsfiddle http://jsfiddle.net/RxDa5/
Please help.
Have a look at the MDN documentation:
The replacement string can include the following special replacement patterns:
$$ Inserts a "$".
So you have to do:
adHtmltext.replace("this", "$$$$Ashok");
See also Javascript string replace weirdness -- $$$$ gets collapsed to $$ -- what's the reason behind this result?.
$$ is the escape code for $, since $ is the escape code for a regex backreference. Unfortunately, you need this:
var adHtmltext ="this is ashok"
adHtmltext = adHtmltext.replace("this", "$$$$Ashok");
alert(adHtmltext );
The dollar sign is a reserved character for .replace()
Indeed, in your jsFiddle code, right at the top, you've used it for it's reserved purpose -- ie the $1 that you've got in there to capture part of the expression.
$$ is used to escape a dollar sign. You need two dollar signs in this context for every single dollar sign you actually want.
This is because otherwise you couldn't have the string $1 in your output.
The .replace method will also accept regular expressions as the first argument, and if you group a portion of the text, you can include it in your output text with a "back-reference" using the '$' character and a number specifying which group to use ($1, $2, etc).
Because the '$' has a special meaning in this context, it needs to be escaped, and '$$' is the escape sequence to produce a normal '$', so you just need '$$$$Ashok' in your code.
There are special patterns that can be included in the string that you replace the target pattern with, and a string with '$$' is one of them. See the Mozilla MDN docs for a better reference.
In your case specifically, '$$' becomes '$' as certain combinations of other characters with '$', like '$&' are reserved for matching with certain substrings. If you want your replacement to work, just use '$$$$Ashok', which will become '$$Ashok' in the final string.
Any custom replacer function can solve this problem more elegantly. You just have to return the intended string from it and it will be replaced as it is.
function customReplacer() {
return "$$Ashok";
}
adHtmltext = adHtmltext.replace("this", customReplacer);
Looking for a generic solution, I obtained the following:
var input = prompt( 'Enter input:' ) || '';
var result = 'foo X bar X baz'.replace( /X/g, input.replace( /\$/g, '$$$$' ) );
It works:
input: $$
result: foo $$ bar $$ baz
input: $&
result: foo $& bar $& baz
But it's a bit tricky, because of the multi-level $ escaping. See that $$$$ in the inner replace...
So, I tried using a callback, to which special replacement patterns aren't applied:
var result = 'foo X bar X baz'.replace( /X/g, function () {
var input = prompt( 'Enter input:' ) || '';
return input;
} );
It works too, but has a caveat: the callback is executed for each replacement. So in the above example, the user is prompted twice...
Finally, here is the fixed code for the "callback" solution, by moving the prompt out of the replace callback:
var input = prompt( 'Enter input:' ) || '';
var result = 'foo X bar X baz'.replace( /X/g, function () {
return input;
} );
To summarize, you have two solutions:
Apply a .replace(/\$/g, '$$$$') escaping on the replacement string
Use a callback, which does nothing more than just returning the replacement string
MDN reference: String.prototype.replace()#Description
I have the following string:
This *is* a *test*!
I want to bold the words surrounded by the * characters (so "is" and "test" in the example).
I have the following JavaScript code:
var data = "This *is* a *test*!";
return data.replace(/\*(.*)\*/g, <b>$1</b>);
When the string is returned, I get the following:
This <b>is* a *test</b>!
How can I change the pattern or basic code in order to do the replacement the way I want it?
SO messed with my HTML...
var result = "This *is* a *test*!".replace(/\*(.*?)\*/gi, "<b>$1</b>");
You need to make the pattern non-greedy by adding the ?-operator after the *:
var data = "This *is* a *test*!";
return data.replace(/\*(.*?)\*/g, "<b>$1</b>");
Here is a reference for JavaScript RegExp from Mozilla Developer Center.