How to make replace() global in JavaScript - javascript

I know this question had been asked lot of time but i could not find solution. I have some smilies which each of them has code to be rendered as smiley using replace() , but I get syntax error, I don't know why and how to render my code :/ to smiley
txt = " Hi :/ ";
txt.replace("/\:/\/g","<img src='img/smiley.gif'>");

Your regular expression doesn't need to be in quotes. You should escape the correct / forward slash (you were escaping the wrong slash) and assign the replacement, since .replace doesn't modify the original string.
txt = " Hi :/ ";
txt = txt.replace(/:\//g,"<img src='img/smiley.gif'>");
Based on jonatjano's brilliant deduction, I think you should add a little more to the regular expression to avoid such calamities as interfering with URLs.
txt = txt.replace(/:\/(?!/)/g,"<img src='img/smiley.gif'>");
The above ensures that :// is not matched by doing a negative-lookahead.

There are two problems in the first argument of replace() it escapes the wrong characters and it uses a string that seems to contain a regex instead of a real RegExp.
The second line should read:
txt.replace(/:\//g,"<img src='img/smiley.gif'>");
/:\//g is the regex. The first and the last / are the RegExp delimiters, g is the "global" RegExp option (String.replace() needs a RegExp instead of a string to do a global replace).
The content of the regex is :/ (the string you want to find) but because / has a special meaning in a RegExp (see above), it needs to be escaped and it becomes :\/.

Related

Javascript replace expression explained

I have the following function:
function replace(path) {
return path.replace(/\//g, '.').replace(/^\./, '');
};
Can you please explain what exactly is doing? I have some hard time understanding it mostly because of the slashes and escapes.
I know it replaces something with something. :)
return path.replace(/\//g, '.').replace(/^\./, '');
The / at the start and end are delimiters of regex.
The \ inside it will escape the following character(\ and .).
/\//g: Will find all(g: global flag) the / in the string and will replace it by .
/^\./: Will find the . at the start(^) of the string and will remove it
Replace / with ., and then replace . at the beginning of string with an empty string.
Let's assume that path is a string. strings in javascript, like everything else, are objects. Among other things, they have a replace function. You can read about it here.
Those things with the slashes are called regular expressions, or RegExs for short. You can read about them here and here. They are very useful and often used for manipulating strings with operations like replace.

How to find out if a given string is HTML Escaped or not?

Is there any method to find out if the given string is HTML Escaped or not?
Consider the following javascript code:
<script>
var str="hello";
var str_esc=escape(str);
document.write(isHTMLEscaped(str)) // *Should print False*
document.write(isHTMLEscaped(str_esc)); // *Should print True*
</script>
Is there any method equivalent to isHTMLEscaped in the above case?
I found that using
escape(unescape(str))
will always provide an escaped string. And the unescape string will do nothing unless the string itself contains escaped expressions.
Note: should have used encodeURI(decodeURI(str)) instead as escape is now depreciated.
As "hello"==escape("hello"), no, you can't at all guess if escaping was applied.
If you want to know if it's probable that the string has been escaped, then you might test
var wasProbablyEscaped = /%\d\d/.test(str);
var wasProbablyNotEscaped = !wasProbablyEscaped && /%\d\d/.test(escape(str));
as escaping adds % followed by two digits when something has to be escaped. But you can't be totally sure as some strings don't change when you escape them.
In your case, I'd probably advise you not to escape if wasProbablyEscaped is true.

RegExp for remove first and last char and turn ending double slashes into single

I have the following Javascript code to obtain the inner string from an RegExp:
Function.prototype.method = function (name,func){
this.prototype[name] = func;
return this;
};
RegExp.method('toRawString', function(){
return this.toString().replace(/^.(.*).$/,"$1");
});
The purpose of this, is to avoid in string double quoting. For example, if you have a Windows file path "C:\My Documents\My Folder\MyFile.file", you can use it like the following:
alert(/C:\My Documents\My Folder\MyFile.file/.toRawString());
However it is not working for ""C:\My Documents\My Folder\" since it causes syntax error. The only way to avoid it is to keep double quoting at the end of the string. Thus it will be written
alert(/C:\My Documents\My Folder\\/.toRawString());
The fact is any odd number of back slashes on the end of the string will be an error, so all ending back slashes must be double escaped. It will not be hard to use a multiple line small implementation, but are there any single RegExp solution?
NOTE
When using toRawString the RegExp object for this is usually NOT going to be used for any other purpose except for that method. I just want to use the syntax of RegExp to avoid double back slashes in source code. Unfortunately the ending double slashes cannot be easily avoid. I think another workaround is to force a space at the end but that is another question then.
UPDATE
I finally solved the "another question" and posted the code here.
OK, I get what you're trying to do! It's hacky : )
Try something like:
return this.toString().slice(1, -1).replace(/\\+$/, '\\')
Hope that helps.
If you want to include the double quotes in the string just wrap it with single quotes.
s = '"C:\\My Documents\\My Folder\\MyFile.file"'
console.log(s) // Output => "C:\My Documents\My Folder\MyFile.file"
This produces a syntax error:
/C:\My Documents\/
But that regular expression could be written correctly like this:
/C:\\My Documents\\/
Or like this:
new RegExp("C:\\\\My Documents\\\\")
I think your function is just fine and is returning a correct result. Regular expressions just can't end with an unpaired backslash. It's not that you're double escaping - you're just escaping the escape character.
This would produce an error too:
new RegExp("C:\\My Documents\\")
A regular expression like this, for instance, can't be written without a pair of backslashes:
/C:\\What/
Without the second backslash, \W would be interpreted as a special character escape sequence. So escaping the escape character isn't only necessary at the end. It's required anywhere it might be interpreted as the beginning of an escape sequences. For that reason, it might be a good rule of thumb to always use two backslashes to indicate a backslash literal in a regular expression.

JavaScript backslash (\) in variables is causing an error

In Javascript, when I put a backslash in some variables like:
var ttt = "aa ///\\\";
var ttt = "aa ///\";
Javascript shows an error.
If I try to restrict user in entering this character, I also get an error:
(("aaa ///\\\").indexOf('"') != -1)
Restricting backslashes from user input is not a good strategy, because you have to show an annoying message to the user.
Why am I getting an error with backslash?
The backslash (\) is an escape character in Javascript (along with a lot of other C-like languages). This means that when Javascript encounters a backslash, it tries to escape the following character. For instance, \n is a newline character (rather than a backslash followed by the letter n).
In order to output a literal backslash, you need to escape it. That means \\ will output a single backslash (and \\\\ will output two, and so on). The reason "aa ///\" doesn't work is because the backslash escapes the " (which will print a literal quote), and thus your string is not properly terminated. Similarly, "aa ///\\\" won't work, because the last backslash again escapes the quote.
Just remember, for each backslash you want to output, you need to give Javascript two.
You may want to try the following, which is more or less the standard way to escape user input:
function stringEscape(s) {
return s ? s.replace(/\\/g,'\\\\').replace(/\n/g,'\\n').replace(/\t/g,'\\t').replace(/\v/g,'\\v').replace(/'/g,"\\'").replace(/"/g,'\\"').replace(/[\x00-\x1F\x80-\x9F]/g,hex) : s;
function hex(c) { var v = '0'+c.charCodeAt(0).toString(16); return '\\x'+v.substr(v.length-2); }
}
This replaces all backslashes with an escaped backslash, and then proceeds to escape other non-printable characters to their escaped form. It also escapes single and double quotes, so you can use the output as a string constructor even in eval (which is a bad idea by itself, considering that you are using user input). But in any case, it should do the job you want.
You have to escape each \ to be \\:
var ttt = "aa ///\\\\\\";
Updated: I think this question is not about the escape character in string at all. The asker doesn't seem to explain the problem correctly.
because you had to show a message to user that user can't give a name which has (\) character.
I think the scenario is like:
var user_input_name = document.getElementById('the_name').value;
Then the asker wants to check if user_input_name contains any [\]. If so, then alert the user.
If user enters [aa ///\] in HTML input box, then if you alert(user_input_name), you will see [aaa ///\]. You don't need to escape, i.e. replace [\] to be [\\] in JavaScript code. When you do escaping, that is because you are trying to make of a string which contain special characters in JavaScript source code. If you don't do it, it won't be parsed correct. Since you already get a string, you don't need to pass it into an escaping function. If you do so, I am guessing you are generating another JavaScript code from a JavaScript code, but it's not the case here.
I am guessing asker wants to simulate the input, so we can understand the problem. Unfortunately, asker doesn't understand JavaScript well. Therefore, a syntax error code being supplied to us:
var ttt = "aa ///\";
Hence, we assume the asker having problem with escaping.
If you want to simulate, you code must be valid at first place.
var ttt = "aa ///\\"; // <- This is correct
// var ttt = "aa ///\"; // <- This is not.
alert(ttt); // You will see [aa ///\] in dialog, which is what you expect, right?
Now, you only need to do is
var user_input_name = document.getElementById('the_name').value;
if (user_input_name.indexOf("\\") >= 0) { // There is a [\] in the string
alert("\\ is not allowed to be used!"); // User reads [\ is not allowed to be used]
do_something_else();
}
Edit: I used [] to quote text to be shown, so it would be less confused than using "".
The backslash \ is reserved for use as an escape character in Javascript.
To use a backslash literally you need to use two backslashes
\\
If you want to use special character in javascript variable value, Escape Character (\) is required.
Backslash in your example is special character, too.
So you should do something like this,
var ttt = "aa ///\\\\\\"; // --> ///\\\
or
var ttt = "aa ///\\"; // --> ///\
But Escape Character not require for user input.
When you press / in prompt box or input field then submit, that means single /.

JavaScript/jQuery removing character 160 from a node's text() value - Regex

$('#customerAddress').text().replace(/\xA0/,"").replace(/\s+/," ");
Going after the value in a span (id=customerAddress) and I'd like to reduce all sections of whitespace to a single whitespace. The /\s+/ whould work except this app gets some character 160's between street address and state/zip
What is a better way to write this? this does not currently work.
UPDATE:
I have figured out that
$('.customerAddress').text().replace(/\s+/g," ");
clears the 160s and the spaces.
But how would I write a regex to just go after the 160s?
$('.customerAddress').text().replace(String.fromCharCode(160)," ");
didn't even work.
Note: I'm testing in Firefox / Firebug
Regarding just replacing char 160, you forgot to make a global regex, so you are only replacing the first match. Try this:
$('.customerAddress').text()
.replace(new RegExp(String.fromCharCode(160),"g")," ");
Or even simpler, use your Hex example in your question with the global flag
$('.customerAddress').text().replace(/\xA0/g," ");
\s does already contain the character U+00A0:
[\t\n\v\f\r \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]
But you should add the g modifier to replace globally:
$('#customerAddress').text().replace(/\s+/g, " ")
Otherwise only the first match will be replaced.
Sorry if I'm being obvious (or wrong), but doesn't .text() when called w/o parameters just RETURNS the text? I mean, I don't know if you included the full code or just an excerpt, but to really replace the span you should do it like:
var t = $('#customerAddress').text().replace(/\xA0/,"").replace(/\s+/," ");
$('#customerAddress').text(t);
Other than that, the regex for collapsing the spaces seems OK, I'm just not sure about the syntax of your non-printable char there.

Categories