Javascript replace issue with $ [duplicate] - javascript

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

Related

Optional Chaining in typescript understanding [duplicate]

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

simple javascript replace function [duplicate]

I have a string like aman/gupta and I want to replace it to aman$$gupta and for that I am using JavaScript replace method as follows:
let a = "aman/gupta"
a = a.replace("/", "$")
console.log(a) // 'aman$gupta'
a = "aman/gupta"
a = a.replace("/", "$$")
console.log(a) // 'aman$gupta'
a = "aman/gupta"
a = a.replace("/", "$$$")
console.log(a) // 'aman$$gupta'
Why are the 1st and 2nd case identical and I get the expected result when I use $$$ instead of $$?
It’s because $$ inserts a literal "$".
So, you need to use:
a = "aman/gupta";
a = a.replace("/", "$$$$"); // "aman$$gupta"
See the following special patterns:
Pattern
Inserts
$$
Inserts a "$".
$&
Inserts the matched substring.
$`
Inserts the portion of the string that precedes the matched substring.
$'
Inserts the portion of the string that follows the matched substring.
$n
Where n is a non-negative integer less than 100, inserts the _n_th parenthesized submatch string, provided the first argument was a RegExp object.
$<Name>
Where Name is a capturing group name. If the group is not in the match, or not in the regular expression, or if a string was passed as the first argument to replace instead of a regular expression, this resolves to a literal (e.g., "$<Name>").
Also you can use split and join for better performance and $ isn't special for those functions.
var a = "aman/gupta"
a = a.split('/').join('$$')
alert(a); // "aman$$gupta"
To avoid the need to escape special characters you can use anonymous function as a replacer
a = "aman/gupta";
a = a.replace("/", function() {return "$$"});
console.log(a); // "aman$$gupta"
String.prototype.replace() documentation
Specifying a function as a parameter
You can specify a function as the second parameter. In this case, the function will be invoked after the match has been performed. The function's result (return value) will be used as the replacement string. (Note: the above-mentioned special replacement patterns do not apply in this case.) Note that the function will be invoked multiple times for each full match to be replaced if the regular expression in the first parameter is global.
The replace method provides replacement patterns that start with a dollar sign. One of them is $$ which inserts a single $. A single dollar sign in the replacement string will result in a literal one.
So if you want clean literal dollar signs, use $$ replacement patterns accordingly:
console.log('aman/gupta'.replace('/','$$')); // aman$gupta
console.log('aman/gupta'.replace('/','$$$$')); // aman$$gupta
console.log('aman/gupta'.replace('/','$$$$$$')); // aman$$$gupta
In regular expression replace with groups, if replacement is a variable, it needs to dollar sign escaped. Otherwise there will be bugs.
function escapeDollarSign(str) {
return str.replace(/\$/g, "$$$$")
}
Use below code its working for me.
var dollar = "$$$$";
console.log('abhishe/kadam'.replace('/', dollar.replace(new RegExp('\\$', 'g'), '$$$')));

Javascript - When a string does not Match itself [duplicate]

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+'));

Javascript: Difference in Regex String and Regex [duplicate]

This question already has answers here:
Differences between Javascript regexp literal and constructor
(2 answers)
Closed 7 years ago.
I have to put a given variable into a regular expression. When I do it with hard coded data it works. Here is my code for that
/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!ccarn).)*$/
This should ( and does ) look for a word (password in this case) that is case sensitive, has at least one capitol and one lowercase letter, and one number or symbol. It cannot, however, contain the word "ccarn" in it. Again when I put this in as my regex all works out. When I try to turn it into a string that gets passed in, it doesn't work. Here is my code for that
var regex = new RegExp('/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$/');
I feel like I may just be missing something in translation/transition, but can't seem to get it right. TIA
When you use the new RegExp() constructor to construct a regex from a string, you shouldn't include the leading and trailing / within the string. The /.../ form is only to be used when specifying a regex literal, which isn't what you're doing here.
When you do, say, var r = new RegExp('/foo/'), the regex you're actually getting is equivalent to doing var r = /\/foo\//, which clearly isn't what you want. So your constructor should actually look like this:
var regex = new RegExp('^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$');
// ↑↑ ↑↑
// no "/" at the locations pointed to above
You probably also need to double your backslashes (since backslashes are escape characters in strings, but not in regex literals). So, [0-9##$-/:-?{-~!"^_`\[\]] needs to become [0-9##$-/:-?{-~!"^_`\\[\\]].
If you look closely the '/' character gets delimited when you give it inside the quotes so essentially the
var regex = new RegExp('/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$/');
The regular expression would be like this
/\/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-\/:-?{-~!"^_`[]])+((?!ccarn).)*$\//
The right way to go is to remove the '/' character from the RegEx and it should work
var regex = new RegExp('/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-/:-?{-~!"^_`\[\]])+((?!' + $scope.username + ').)*$/');
The output for the above would be
/^(?=.*[a-z])+(?=.*[A-Z])+(?=.*[0-9##$-\/:-?{-~!"^_`[]])+((?!ccarn).)*$/
which is exactly what you need ?
Hope it helps
Please before doing anything else, read a regex tutorial!
Mistakes:
A lookahead is a zero width assertion ( in other words, it's only a test and doesn't match anything ), putting a quantifier for a zero width assertion doesn't make any sense: (?=.*[a-z])+ (it is like repeating something empty, zero or more times. Note that the regex engine will protest if you write something like this.)
When you use the oop syntax to define a pattern (ie:var pattern = new RegExp("...), you don't need to add delimiters. You need to put double backslashes instead simple backslashes.

Split string in JavaScript using a regular expression

I'm trying to write a regex for use in javascript.
var script = "function onclick() {loadArea('areaog_og_group_og_consumedservice', '\x26roleOrd\x3d1');}";
var match = new RegExp("'[^']*(\\.[^']*)*'").exec(script);
I would like split to contain two elements:
match[0] == "'areaog_og_group_og_consumedservice'";
match[1] == "'\x26roleOrd\x3d1'";
This regex matches correctly when testing it at gskinner.com/RegExr/ but it does not work in my Javascript. This issue can be replicated by testing ir here http://www.regextester.com/.
I need the solution to work with Internet Explorer 6 and above.
Can any regex guru's help?
Judging by your regex, it looks like you're trying to match a single-quoted string that may contain escaped quotes. The correct form of that regex is:
'[^'\\]*(?:\\.[^'\\]*)*'
(If you don't need to allow for escaped quotes, /'[^']*'/ is all you need.) You also have to set the g flag if you want to get both strings. Here's the regex in its regex-literal form:
/'[^'\\]*(?:\\.[^'\\]*)*'/g
If you use the RegExp constructor instead of a regex literal, you have to double-escape the backslashes: once for the string literal and once for the regex. You also have to pass the flags (g, i, m) as a separate parameter:
var rgx = new RegExp("'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'", "g");
while (result = rgx.exec(script))
print(result[0]);
The regex you're looking for is .*?('[^']*')\s*,\s*('[^']*'). The catch here is that, as usual, match[0] is the entire matched text (this is very normal) so it's not particularly useful to you. match[1] and match[2] are the two matches you're looking for.
var script = "function onclick() {loadArea('areaog_og_group_og_consumedservice', '\x26roleOrd\x3d1');}";
var parameters = /.*?('[^']*')\s*,\s*('[^']*')/.exec(script);
alert("you've done: loadArea("+parameters[1]+", "+parameters[2]+");");
The only issue I have with this is that it's somewhat inflexible. You might want to spend a little time to match function calls with 2 or 3 parameters?
EDIT
In response to you're request, here is the regex to match 1,2,3,...,n parameters. If you notice, I used a non-capturing group (the (?: ) part) to find many instances of the comma followed by the second parameter.
/.*?('[^']*')(?:\s*,\s*('[^']*'))*/
Maybe this:
'([^']*)'\s*,\s*'([^']*)'

Categories