How to replace HTML special character in javascript? - javascript

var Value="!##$'&\";
if (value.indexOf("'") > 0) {
value = value.replace(/'/g, "'");
}
All Text is replaced except last character "\".
How do i replace it with same.

I have new information about this solution from #MarcoS:
var value = "!##$'&\\";
value = value.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#' + i.charCodeAt(0) + ';';
});
I am not sure when it started, but as of today 2019/07/10, this code will not work in chrome, but it does work in firefox/safari. It will cause the lowercase 's' character to trip the regex and output as encoded s A coworker of mine found that this character \u017f, now in the unicode standard, and causes this code to act strangely:
http://www.fileformat.info/info/unicode/char/17f/index.htm
If you instead use the following, it should work in all browsers:
var value = "!##$'&\\";
value = value.replace(/[\u00A0-\u017e\u0180-\u9999]/gim, function(i) {
return '&#' + i.charCodeAt(0) + ';';
});

This is the currently 'accepted' code to convert all (or a range of them) possible unicode characters to their equivalent HTML entity:
var value = "!##$'&\\";
value = value.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
return '&#' + i.charCodeAt(0) + ';';
});

There is a syntax error, that once fixed will also replace the \ character:
You need an extra backslash because backslash is a special character and needs to be escaped.
var value= "!##$'&\\";

Related

Javascript Regex: exclude result if preceded by href="

I'm struggling to get a string replaced in Javascript by a regex matching pattern.
I want to replace all matches of {{$myparam}} to be surrounded by a span tag.
This works (see code below). But I want to prevent replacements when a match is preceded by href=".
Example: href="{{$myparam}} must NOT be replaced.
{{$myparam}} MUST be replaced.
myparam can be any text string.
var highlighted = html.replace(/(\{\{(.*?)\}\})/g, function highlight(x) {
return "<span class='highlight'>" + x + "</span>";
});
I've checked out numerous examples in other threads, but I cannot find a solution that works for my case.
You could use
var subject = 'href="{{$myparam}}" or any other {{$myparam}}';
var regex = /"[^"]*"|(\{\{(.*?)\}\})/g;
replaced = subject.replace(regex, function(m, group1) {
if (typeof group1 == 'undefined') return m;
else return "<span class='highlight'>" + group1 + "</span>";
});
alert(replaced);
# href="{{$myparam}}" or any other <span class='highlight'>{{$myparam}}</span>
See a demo on regex101.com.
The idea here is to check for
not_interesting|not_interesting_either|(very_interesting)
and check for the presence of a captured group. You can put anything not interesting to the left as in this example: "[^"]*" (that is anything between double quotes).
If you want to read more on the subject, have a look here.
This seems a bit simpler, just make the href part optional:
mystring = 'this has {{$param1}} and {{$param2}} and href="{{$param3}}" too';
console.log(mystring
.replace(/(href=.)?\{\{([^{} ]+)\}\}/g,
function (match,chk,param) {
return "undefined" !== typeof(chk)
? match
: '<span class="highlight">' + param + '</span>';
}));
The second argument to the callback function is the 'check' part, and the third argument is the captured parameter name. Since the check part is optional and it's fairly precise, it'll only be defined at all if it's 'href="'.
Output, with newlines added for readability:
this has <span class="highlight">$param1</span>
and <span class="highlight">$param2</span>
and href="{{$param3}}" too

How to compress IPV6 address using javascript?

I have seen the code to compress IPV6 in java.
The link specifies the same.
Below is the code in Java . String resultString = subjectString.replaceAll("((?::0\\b){2,}):?(?!\\S*\\b\\1:0\\b)(\\S*)", "::$2");
But in Javascript I am confused as how can I get the regex expression to match the same . Can you share some pointers here?
Example : fe80:00:00:00:8e3:a11a:2a49:1148
Result : fe80::8e3:a11a:2a49:1148
There's a couple problems with the other answer by #ClasG:
If the repeating zeroes are at the beginning of the IPv6 address or it's all zeroes, only 1 colon is replaced.
If the repeating zeroes are at the end, they're not replaced.
I suggest using the regex \b:?(?:0+:?){2,} and have it replaced with :: (two colons)
Regex101 tests
JavaScript example:
var ips = [
'2001:0db8:ac10:0000:0000:0000:0000:ffff',
'2001:0db8:ac10:0000:0000:0000:0000:0000',
'0:0:0:0:0:2001:0db8:ac10',
'2001:0db8:ac10:aaaa:0000:bbbb:cccc:ffff',
'2001:0db8:ac10:0000:0000:bbbb:00:00'
];
for (var i = 0; i < ips.length; i++) {
document.write(ips[i].replace(/\b:?(?:0+:?){2,}/, '::') + "<br>");
}
Note: The Regex101 tests replace multiple repeating groups of zeroes. In XYZ programming language, you'll have to limit the number of replacements to 1. In JavaScript, you omit the global flag. In PHP, you set the $limit for preg_replace to 1.
You can do it by replacing
\b(?:0+:){2,}
with
:
function compIPV6(input) {
return input.replace(/\b(?:0+:){2,}/, ':');
}
document.write(compIPV6('2001:db8:0:0:0:0:2:1') + '<br/>');
document.write(compIPV6('fe80:00:00:00:8e3:a11a:2a49:1148' + '<br/>'));
Check it out at regex101.
You can use this method in order to compress IPv6 AND remove leading 0s:
function compressIPV6(input) {
var formatted = input.replace(/\b(?:0+:){2,}/, ':');
var finalAddress = formatted.split(':')
.map(function(octet) {
return octet.replace(/\b0+/g, '');
}).join(':');
return finalAddress;
}
document.write(compressIPV6('2001:0db8:0000:0000:0000:0000:1428:57ab') );
You can use a function that considers all of the needed cases:
const compressIPV6 = (ip) => {
//First remove the leading 0s of the octets. If it's '0000', replace with '0'
let output = ip.split(':').map(terms => terms.replace(/\b0+/g, '') || '0').join(":");
//Then search for all occurrences of continuous '0' octets
let zeros = [...output.matchAll(/\b:?(?:0+:?){2,}/g)];
//If there are occurences, see which is the longest one and replace it with '::'
if (zeros.length > 0) {
let max = '';
zeros.forEach(item => {
if (item[0].replaceAll(':', '').length > max.replaceAll(':', '').length) {
max = item[0];
}
})
output = output.replace(max, '::');
}
return output;
}
document.write(compressIPV6('38c1:3db8:0000:0000:0000:0000:0043:000a') + '<br/>');
document.write(compressIPV6('0000:0000:0000:0000:38c1:3db8:0043:000a') + '<br/>');
document.write(compressIPV6('38c1:3db8:0000:0043:000a:0000:0000:0000') + '<br/>');
document.write(compressIPV6('38c1:0000:0000:3db8:0000:0000:0000:12ab') + '<br/>');
If there's more than one occurrence of consecutive '0' octets of the same length, it will only replace the first one. This will work regardless if the repeating zeroes are at the beginning, at the middle or at the end.

How to turn a String with square brackets and forward slashes + variables into a regex?

I've tried to get my head around regex, but I still can't get it.
I want to turn the following String + some variables into a regex:
"[url href=" + objectId + "]" + objectId2 + "[/url]"
I tried the following, since I read somewhere that brackets and slashes need to be escaped:
/\[url href=/ + objectId + /\]/ + objectId2 + /\[\/\url\]/g
But that isn't working.
I want to use it to replace the whole expression into HTML wherever it matches in a String.
You are correct that brackets and backslashes need to be escaped in a regular expression, but you can't create a regex by adding together regex literals like your /\[url href=/ + objectId + /\]/ attempt. To build a regex dynamically like that you have to use string concatenation and pass the result to new RegExp(). So as a starting point for your text you'd need this:
new RegExp("\\[url href=" + objectId + "\\]" + objectId2 + "\\[/url\\]")
Note all of the double-backslashes - that's because backslashes need to be escaped in string literals, so "\\[" creates a string containing a single backslash and then a bracket, which is what you want in your regex.
But if you want to extract the matched href and content for use in creating an anchor then you need capturing parentheses:
new RegExp("\\[url href=(" + objectId + ")\\](" + objectId2 + ")\\[/url\\]")
But that's still not enough for your purposes because objectId and objectId2 could (or will, given the first is a url) contain other characters that need to be escaped in a regex too, e.g., .+?(), etc. So here's a function that can escape all of the necessary characters:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
We can't just call that function on the whole thing, because you need unescaped parentheses for your capturing sub matches, so just call it on the two variables:
var urlRegex = new RegExp("\\[url href=("
+ escapeStringForRegex(objectId)
+ ")\\]("
+ escapeStringForRegex(objectId2)
+ ")\\[/url\\]");
Kind of messy, but seems to do the job as you can see here:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function createAnchors(str, objectId, objectId2) {
var urlRegex = new RegExp("\\[url href=(" + escapeStringForRegex(objectId) + ")\\](" + escapeStringForRegex(objectId2) + ")\\[/url\\]", "g");
return str.replace(urlRegex, "<a href='$1'>$2</a>");
}
document.querySelector("button").addEventListener("click", function() {
var str = document.getElementById("input").value;
var objectId = document.getElementById("objectId").value;
var objectId2 = document.getElementById("objectId2").value;
document.getElementById("output").value =
createAnchors(str, objectId, objectId2);
});
textarea { width : 100%; height: 80px; }
Input:<br><textarea id="input">This is just some text that you can edit to try things out. [url href=http://test.com.au?param=1]Test URL[/url]. Thanks.</textarea>
ObjectId:<input id="objectId" value="http://test.com.au?param=1"><br>
ObjectId2:<input id="objectId2" value="Test URL"><br>
<button>Test</button>
<textarea id="output"></textarea>
Note that the above searches only for [url]s in your string that have the particular href and content specified in the objectId and objectId2 variables. If you just want to change all [url]s into anchors regardless of what href and text they contain then use this:
.replace(/\[url href=([^\]]+)\]([^\]]+)\[\/url\]/g, "<a href='$1'>$2</a>")
Demo:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function createAnchors(str) {
return str.replace(/\[url href=([^\]]+)\]([^\]]+)\[\/url\]/g, "<a href='$1'>$2</a>");
}
document.querySelector("button").addEventListener("click", function() {
var str = document.getElementById("input").value;
document.getElementById("output").value = createAnchors(str);
});
textarea { width : 100%; height: 80px; }
Input:<br><textarea id="input">Testing. [url href=http://test.com.au?param=1]Test URL[/url]. Thanks. Another URL: [url href=https://something.com/test?param=1&param2=123]Test URL 2[/url]</textarea>
<button>Test</button>
<textarea id="output"></textarea>
It's like:
var rx = new RegExp('\\[url\\shref='+objectId+'\\]'+objectId2+'\\[\\/url\\]');
new RegExp("[url href=" + objectId + "]" + objectId2 + "[\url]")
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Check for existence of a keyword within a code string

I’m loading the contents of a JS file using FileReader and dumping the results into a textarea container. I then want to run some checks on the actual JS file.
I know there are probably tools out there for this already (or better ways), but this is for a closed-environment project.
After the textarea contains the content of the JS file as one large string, I need to loop the string and find all instances of parseInt() to check if they have been supplied with a radix.
I would provide code, but I have nothing working at this point. Any ideas?
The following snippet will search the string value of your <textarea> element for parseInt() and output the occurences, with radix where applicable:
var textareaValue = 'var func = function(){' +
'var i = parseInt(1,1);' +
'var j = parseInt(10, 10);' +
'var k = parseInt(3) + j;' +
'};';
occurences = textareaValue.match(/parseInt\(.+?(, ?\d+)?\)/g);
occurences.forEach(function(occurence){
var hasRadix = /, ?\d+\)$/.test(occurence);
document.body.innerHTML += '<p>"' + occurence + '" has ' +
(hasRadix ? 'a' : 'no') + ' radix' +
(hasRadix ? ' (' + occurence.match(/, ?(\d+)\)$/)[1] + ')' : '') +
'.</p>';
});
Note that this is no actual syntax interpretation, it’s merely text analysis. You will have to go from the result, which comprises all the occurences of parseInt() as strings. Also, JavaScript allows whitespace, comments, expressions and other witchcraft at the text passage in question. You might to have to check for anything.
The actual regex /parseInt\(.+?(, ?\d+)?\)/g will demand…
parseInt( at the beginning of the match
any characters (might need to be expanded to include brackets, etc. by :punct:)
as optional group, determining whether a radix is supplied or not:
a comma, an optional space (might need to respond to any number of whitespace using *)
at least one digit (might need to limit to {1,2}, because only 2 to 36 are valid)
a trailing closing bracket.
The following function should be able to tell the difference between usages of parseInt with radix versus its usages without radix by simplistic regex matching:
function have_radix(str){
parseIntRegex = /parseInt\(.+?\)/g;
parseIntRegexWithRadix = /parseInt\(.+?(,.+?\))/g;
indices = [];
while ( (result = parseIntRegex.exec(str)) ) {
indices.push(result.index);
}
count = indices.length;
indices = [];
while ( (result = parseIntRegexWithRadix.exec(str)) ) {
indices.push(result.index);
}
diff = count - indices.length;
return diff;
}

Javascript/Regex: Expression works in one environment and not another

I am trying to only allow alphanumeric entry or these characters:'()-_. (with the "." included)
Using regexpal.com I entered this regular expression: [^a-zA-Z0-9()\.'\-\_ ]
It is correctly identifying * and # as a match. What's baffling is that I have that same exact expression in my javascript on an .aspx page and it is not catching * or #. I have confirmed that is indeed entering that function and that the expression evaluates. Here is that code:
$(".validateText").keyup(function (e) {
var matchPattern = "[^a-zA-Z0-9()\.'\-\_ ]";
var regEx = new RegExp(matchPattern);
console.log("Regex: " + regEx + "\nValue of " + e.target.id + " is: " + e.target.value);
if (regEx.test(e.target.value)) {
console.log("Found invalid data.");//I don't get here with # or *
var failingChar = e.target.value.length - 1;
e.target.value = e.target.value.substring(0, failingChar);
}
});
Rather than using string literals to define regexes, use regex literals.
var regEx = /[^a-zA-Z0-9()\.'\-\_ ]/;
String literals interpret backslashes as escape characters, so they need to be escaped. Regex literals don't require this.
As per Bergi's suggestion, you wouldn't even need to escape all those characters.
/[^a-zA-Z0-9().'_ -]/
You could probably even use the general \w character.
/[^\w().' -]/
var matchPattern = "[^a-zA-Z0-9()\\.'\\-\\_ ]";
Would work.

Categories