Related
Is the if statement in the following example redundant?
if (str[0] === ' ') {
str = str.trimStart()
}
It seems unnecessary to me since trimStart() does not seem to have any negative effect on a string without a space at the beginning. Additionally, if the string does have a space at the beginning, you are running twice as many operations as needed.
Is the if statement ever necessary in situations like the one above?
Given the edited code, there's one situation where the if statement could be useful - if the string starts with a newline (which counts as whitespace, and would be trimmed), not a plain space. For example:
const parseStr = (str) => {
if (str[0] === ' ') {
str = str.trimStart()
}
console.log(str.length);
};
parseStr('\nfoo');
parseStr(' foo');
parseStr('foo');
If trimStart was called unconditionally, the newline would be trimmed regardless:
const parseStr = (str) => {
str = str.trimStart()
console.log(str.length);
};
parseStr('\nfoo');
parseStr(' foo');
parseStr('foo');
The if is not necessary, but you should save the trimmed value somewhere, like
str = str.trimStart();
-- Edit --
"Is the 'if' ever necessary...?"
The test that you are doing in the original is redundant. But you might want to check that str has a value and/or check that this value is a string before calling trimStart(), like
if (str && typeof str === 'string') ...
The if block isn't necessary since the trimStart function won't have any effect if there is not space in the beginning of the string. Having the if statement does not have any effect over it and wouldn't really have any real performance benefits either.
I'm trying to remove whitespace from an argument passed by a HTML form into a function using the trim() method. The function then lists the addresses that match that postcode.
var postCodes = {
N48LP: {
address: ['59, White Gardens', '54, White Gardens', '52, White Gardens', '55, White Gardens']
}
};
function searchCode(arg2){
arg2.trim();
if(typeof postCodes[arg2] === 'undefined') {
document.getElementById('oldpa').innerHTML = 'Postcode not found';
} else {
// code here which prints the list of addresses
}}};
This doesn't work. Where 'N48LP' works, 'N4 8LP' or 'N 48LP' will result in 'Postcode not found'. Could anyone tell me why? Many thanks.
Try replace instead of trim.
arg2.replace(/\s+/, "");
you are looking for: arg2.split(' ').join(''). trim function remove spaces from start and from end of strings only
There are several problems in your code. One is that trim() does not trim the string in-place, this means that it does not mutate the original string. The second one is that trim() does not remove spaces in between characters.
To solve this, you can use replace() with a regex that replaces all occurence of all spaces as empty strings, and then assign such value as an index to be used when checking the postCodes object.
var postCodes = {
N48LP: {
address: ['59, White Gardens', '54, White Gardens', '52, White Gardens', '55, White Gardens']
}
};
function searchCode(arg2) {
// note that you have to make the regex to perform
// a global search to make it function as a trim as well
var index = arg2.replace(/\s+/g, '');
if (typeof postCodes[index] === 'undefined') {
document.getElementById('oldpa').innerHTML += 'Postcode not found';
} else {
// code here which prints the list of addresses
document.getElementById('oldpa').innerHTML += [
'<strong>input: ', arg2.replace(/\s+/g, ' '), '</strong>',
'<pre>', JSON.stringify(postCodes[index], 0, 4), '</pre>'
].join('');
}
}
searchCode('N 48LP');
searchCode(' N48LP ');
searchCode(' N 4 8 L P ');
<div id="oldpa"></div>
Problem is here arg2.trim();. As #DontRelaX said trim() methods does not remove white spaces in the middle of the string. And another problem, considering that this would be a problem, that trim() returns modified string, but does not effect the value of the sting itself.
I need to remove all JavaScript comments from a JavaScript source using the JavaScript RegExp object.
What I need is the pattern for the RegExp.
So far, I've found this:
compressed = compressed.replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, '');
This pattern works OK for:
/* I'm a comment */
or for:
/*
* I'm a comment aswell
*/
But doesn't seem to work for the inline:
// I'm an inline comment
I'm not quite an expert for RegEx and it's patterns, so I need help.
Also, I' would like to have a RegEx pattern which would remove all those HTML-like comments.
<!-- HTML Comment //--> or <!-- HTML Comment -->
And also those conditional HTML comments, which can be found in various JavaScript sources.
Thanks.
NOTE: Regex is not a lexer or a parser. If you have some weird edge case where you need some oddly nested comments parsed out of a string, use a parser. For the other 98% of the time this regex should work.
I had pretty complex block comments going on with nested asterisks, slashes, etc. The regular expression at the following site worked like a charm:
http://upshots.org/javascript/javascript-regexp-to-remove-comments
(see below for original)
Some modifications have been made, but the integrity of the original regex has been preserved. In order to allow certain double-slash (//) sequences (such as URLs), you must use back reference $1 in your replacement value instead of an empty string. Here it is:
/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm
// JavaScript:
// source_string.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1');
// PHP:
// preg_replace("/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/m", "$1", $source_string);
DEMO: https://regex101.com/r/B8WkuX/1
FAILING USE CASES: There are a few edge cases where this regex fails. An ongoing list of those cases is documented in this public gist. Please update the gist if you can find other cases.
...and if you also want to remove <!-- html comments --> use this:
/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*|<!--[\s\S]*?-->$/
(original - for historical reference only)
// DO NOT USE THIS - SEE ABOVE
/(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/gm
try this,
(\/\*[\w\'\s\r\n\*]*\*\/)|(\/\/[\w\s\']*)|(\<![\-\-\s\w\>\/]*\>)
should work :)
I have been putting togethor an expression that needs to do something similar.
the finished product is:
/(?:((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)|(\/\*(?:(?!\*\/).|[\n\r])*\*\/)|(\/\/[^\n\r]*(?:[\n\r]+|$))|((?:=|:)\s*(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))|((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)[gimy]?\.(?:exec|test|match|search|replace|split)\()|(\.(?:exec|test|match|search|replace|split)\((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))|(<!--(?:(?!-->).)*-->))/g
Scary right?
To break it down, the first part matches anything within single or double quotation marks
This is necessary to avoid matching quoted strings
((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)
the second part matches multiline comments delimited by /* */
(\/\*(?:(?!\*\/).|[\n\r])*\*\/)
The third part matches single line comments starting anywhere in the line
(\/\/[^\n\r]*(?:[\n\r]+|$))
The fourth through sixth parts matchs anything within a regex literal
This relies on a preceding equals sign or the literal being before or after a regex call
((?:=|:)\s*(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))
((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)[gimy]?\.(?:exec|test|match|search|replace|split)\()
(\.(?:exec|test|match|search|replace|split)\((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))
and the seventh which I originally forgot removes the html comments
(<!--(?:(?!-->).)*-->)
I had an issue with my dev environment issuing errors for a regex that broke a line, so I used the following solution
var ADW_GLOBALS = new Object
ADW_GLOBALS = {
quotations : /((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)/,
multiline_comment : /(\/\*(?:(?!\*\/).|[\n\r])*\*\/)/,
single_line_comment : /(\/\/[^\n\r]*[\n\r]+)/,
regex_literal : /(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)/,
html_comments : /(<!--(?:(?!-->).)*-->)/,
regex_of_doom : ''
}
ADW_GLOBALS.regex_of_doom = new RegExp(
'(?:' + ADW_GLOBALS.quotations.source + '|' +
ADW_GLOBALS.multiline_comment.source + '|' +
ADW_GLOBALS.single_line_comment.source + '|' +
'((?:=|:)\\s*' + ADW_GLOBALS.regex_literal.source + ')|(' +
ADW_GLOBALS.regex_literal.source + '[gimy]?\\.(?:exec|test|match|search|replace|split)\\(' + ')|(' +
'\\.(?:exec|test|match|search|replace|split)\\(' + ADW_GLOBALS.regex_literal.source + ')|' +
ADW_GLOBALS.html_comments.source + ')' , 'g'
);
changed_text = code_to_test.replace(ADW_GLOBALS.regex_of_doom, function(match, $1, $2, $3, $4, $5, $6, $7, $8, offset, original){
if (typeof $1 != 'undefined') return $1;
if (typeof $5 != 'undefined') return $5;
if (typeof $6 != 'undefined') return $6;
if (typeof $7 != 'undefined') return $7;
return '';
}
This returns anything captured by the quoted string text and anything found in a regex literal intact but returns an empty string for all the comment captures.
I know this is excessive and rather difficult to maintain but it does appear to work for me so far.
This works for almost all cases:
var RE_BLOCKS = new RegExp([
/\/(\*)[^*]*\*+(?:[^*\/][^*]*\*+)*\//.source, // $1: multi-line comment
/\/(\/)[^\n]*$/.source, // $2 single-line comment
/"(?:[^"\\]*|\\[\S\s])*"|'(?:[^'\\]*|\\[\S\s])*'/.source, // - string, don't care about embedded eols
/(?:[$\w\)\]]|\+\+|--)\s*\/(?![*\/])/.source, // - division operator
/\/(?=[^*\/])[^[/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[/\\]*)*?\/[gim]*/.source
].join('|'), // - regex
'gm' // note: global+multiline with replace() need test
);
// remove comments, keep other blocks
function stripComments(str) {
return str.replace(RE_BLOCKS, function (match, mlc, slc) {
return mlc ? ' ' : // multiline comment (replace with space)
slc ? '' : // single/multiline comment
match; // divisor, regex, or string, return as-is
});
}
The code is based on regexes from jspreproc, I wrote this tool for the riot compiler.
See http://github.com/aMarCruz/jspreproc
In plain simple JS regex, this:
my_string_or_obj.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ' ')
a bit simpler -
this works also for multiline - (<!--.*?-->)|(<!--[\w\W\n\s]+?-->)
Simple regex ONLY for multi-lines:
/\*((.|\n)(?!/))+\*/
The accepted solution does not capture all common use cases. See examples here: https://regex101.com/r/38dIQk/1.
The following regular expression should match JavaScript comments more reliably:
/(?:\/\*(?:[^\*]|\**[^\*\/])*\*+\/)|(?:\/\/[\S ]*)/g
For demonstration, visit the following link: https://regex101.com/r/z99Nq5/1/.
This is late to be of much use to the original question, but maybe it will help someone.
Based on #Ryan Wheale's answer, I've found this to work as a comprehensive capture to ensure that matches exclude anything found inside a string literal.
/(?:\r\n|\n|^)(?:[^'"])*?(?:'(?:[^\r\n\\']|\\'|[\\]{2})*'|"(?:[^\r\n\\"]|\\"|[\\]{2})*")*?(?:[^'"])*?(\/\*(?:[\s\S]*?)\*\/|\/\/.*)/g
The last group (all others are discarded) is based on Ryan's answer. Example here.
This assumes code is well structured and valid javascript.
Note: this has not been tested on poorly structured code which may or may not be recoverable depending on the javascript engine's own heuristics.
Note: this should hold for valid javascript < ES6, however, ES6 allows multi-line string literals, in which case this regex will almost certainly break, though that case has not been tested.
However, it is still possible to match something that looks like a comment inside a regex literal (see comments/results in the Example above).
I use the above capture after replacing all regex literals using the following comprehensive capture extracted from es5-lexer here and here, as referenced in Mike Samuel's answer to this question:
/(?:(?:break|case|continue|delete|do|else|finally|in|instanceof|return|throw|try|typeof|void|[+]|-|[.]|[/]|,|[*])|[!%&(:;<=>?[^{|}~])?(\/(?![*/])(?:[^\\\[/\r\n\u2028\u2029]|\[(?:[^\]\\\r\n\u2028\u2029]|\\(?:[^\r\n\u2028\u2029ux]|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}))+\]|\\(?:[^\r\n\u2028\u2029ux]|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}))*\/[gim]*)/g
For completeness, see also this trivial caveat.
If you click on the link below you find a comment removal script written in regex.
These are 112 lines off code that work together also works with mootools and Joomla and drupal and other cms websites.
Tested it on 800.000 lines of code and comments. works fine.
This one also selects multiple parenthetical like ( abc(/nn/('/xvx/'))"// testing line") and comments that are between colons and protect them.
23-01-2016..! This is the code with the comments in it.!!!!
Click Here
I was looking for a quick Regex solution too, but none of the answers provided work 100%. Each one ends up breaking the source code in some way, mostly due to comments detected inside string literals. E.g.
var string = "https://www.google.com/";
Becomes
var string = "https:
For the benefit of those coming in from google, I ended up writing a short function (in Javascript) that achieves what the Regex couldn't do. Modify for whatever language you are using to parse Javascript.
function removeCodeComments(code) {
var inQuoteChar = null;
var inBlockComment = false;
var inLineComment = false;
var inRegexLiteral = false;
var newCode = '';
for (var i=0; i<code.length; i++) {
if (!inQuoteChar && !inBlockComment && !inLineComment && !inRegexLiteral) {
if (code[i] === '"' || code[i] === "'" || code[i] === '`') {
inQuoteChar = code[i];
}
else if (code[i] === '/' && code[i+1] === '*') {
inBlockComment = true;
}
else if (code[i] === '/' && code[i+1] === '/') {
inLineComment = true;
}
else if (code[i] === '/' && code[i+1] !== '/') {
inRegexLiteral = true;
}
}
else {
if (inQuoteChar && ((code[i] === inQuoteChar && code[i-1] != '\\') || (code[i] === '\n' && inQuoteChar !== '`'))) {
inQuoteChar = null;
}
if (inRegexLiteral && ((code[i] === '/' && code[i-1] !== '\\') || code[i] === '\n')) {
inRegexLiteral = false;
}
if (inBlockComment && code[i-1] === '/' && code[i-2] === '*') {
inBlockComment = false;
}
if (inLineComment && code[i] === '\n') {
inLineComment = false;
}
}
if (!inBlockComment && !inLineComment) {
newCode += code[i];
}
}
return newCode;
}
2019:
All other answers are incomplete and full of shortcomings. I take the time to write complete answer that WORK
function stripComments(code){
const savedText = [];
return code
.replace(/(['"`]).*?\1/gm,function (match) {
var i = savedText.push(match);
return (i-1)+'###';
})
// remove // comments
.replace(/\/\/.*/gm,'')
// now extract all regex and save them
.replace(/\/[^*\n].*\//gm,function (match) {
var i = savedText.push(match);
return (i-1)+'###';
})
// remove /* */ comments
.replace(/\/\*[\s\S]*\*\//gm,'')
// remove <!-- --> comments
.replace(/<!--[\s\S]*-->/gm, '')
.replace(/\d+###/gm,function(match){
var i = Number.parseInt(match);
return savedText[i];
})
}
var cleancode = stripComments(stripComments.toString())
console.log(cleancode)
Other answers not working on samples code like that:
// won't execute the creative code ("Can't execute code form a freed script"),
navigator.userAgent.match(/\b(MSIE |Trident.*?rv:|Edge\/)(\d+)/);
function stripComments(code){
const savedText = [];
return code
// extract strings and regex
.replace(/(['"`]).*?\1/gm,function (match) {
savedText.push(match);
return '###';
})
// remove // comments
.replace(/\/\/.*/gm,'')
// now extract all regex and save them
.replace(/\/[^*\n].*\//gm,function (match) {
savedText.push(match);
return '###';
})
// remove /* */ comments
.replace(/\/\*[\s\S]*\*\//gm,'')
// remove <!-- --> comments
.replace(/<!--[\s\S]*-->/gm, '')
/*replace \ with \\ so we not lost \b && \t*/
.replace(/###/gm,function(){
return savedText.shift();
})
}
var cleancode = stripComments(stripComments.toString())
console.log(cleancode)
for /**/ and //
/(?:(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:(?<!\:|\\\|\')\/\/.*))/gm
I wonder if this was a trick question given by
a professor to students. Why? Because it seems
to me it is IMPOSSIBLE to do this, with
Regular Expressions, in the general case.
Your (or whoever's code it is) can contain
valid JavaScript like this:
let a = "hello /* ";
let b = 123;
let c = "world */ ";
Now if you have a regexp which removes everything
between a pair of /* and */, it would break the code
above, it would remove the executable code in the
middle as well.
If you try to devise a regexp that would not
remove comments which contain quotes then
you cannot remove such comments. That applies
to single-quote, double-quotes and back-quotes.
You can not remove (all) comments with Regular
Expressions in JavaScript, it seems to me,
maybe someone can point out a way how to do
it for the case above.
What you can do is build a small parser which
goes through the code character by character
and knows when it is inside a string and when
it is inside a comment, and when it is inside
a comment inside a string and so on.
I'm sure there are good open source JavaScript
parsers that can do this. Maybe some of the
packaging and minifying tools can do this for
you as well.
For block comment:
https://regex101.com/r/aepSSj/1
Matches slash character (the \1) only if slash character is followed by asterisk.
(\/)(?=\*)
maybe followed by another asterisk
(?:\*)
followed by first group of match, or zero or more times from something...maybe, without remember the match but capture as a group.
((?:\1|[\s\S])*?)
followed by asterisk and first group
(?:\*)\1
For block and/or inline comment:
https://regex101.com/r/aepSSj/2
where | mean or and (?=\/\/(.*)) capture anything after any //
or https://regex101.com/r/aepSSj/3
to capture the third part too
all in: https://regex101.com/r/aepSSj/8
DEMO: https://onecompiler.com/javascript/3y825u3d5
const context = `
<html>
<script type="module">
/* I'm a comment */
/*
* I'm a comment aswell url="https://example.com/";
*/
var re = /\\/*not a comment!*/;
var m = /\\//.test("\"not a comment!\"");
var re = /"/; // " thiscommentishandledasascode!
const s1 = "multi String \\
\\"double quote\\" \\
// single commet in str \\
/* multiple lines commet in str \\
secend line */ \\
last line";
const s2 = 's2"s';
const url = "https://example.com/questions/5989315/";
let a = "hello /* ";
let b = 123;
let c = "world */ ";
//public static final String LETTERS_WORK_FOLDER = "/Letters/Generated/Work";
console.log(/*comment in
console.log*/ "!message at console.log");
function displayMsg( // the end comment
/*commet arg1*/ a, ...args) {
console.log("Hello World!", a, ...args)
}
<\/script>
<body>
<!-- HTML Comment //--> or <!-- HTML Comment -->
<!--
function displayMsg() {
alert("Hello World!")
}
//-->
</body>
</html>
`;
console.log("before:\n" + context);
console.log("<".repeat(100));
const save = {'txt':[], 'comment':[], 'regex': []};
const context2 =
context.replace(/(['"`]|\/[\*\/]{0,1}|<!\-\-)(?:(?=(?<=\/\*))[\s\S]*?\*\/|(?=(?<=\/\/)).*|(?=(?<=<!\-\-))[\s\S]*?\-\->|(?=(?<=[\s\=]\/)).+?(?<!\\)\/|(?=(?<=['"`]))[\s\S]*?(?<!\\)\1)/g,
function (m) {
const t = (m[0].match(/["'`]/) && 'txt') || (m.match(/^(\/\/|\/\*|<)/) && 'comment') || 'regex';
save[t].push(m);
return '${save.'+t+'['+(save[t].length - 1)+']}';
}).replace(/[\S\s]*/, function(m) {
console.log("watch:\n"+m);
console.log(">".repeat(100));
/*
##remove comment
save.comment = save.comment.map(_ => _.replace(/[\S\s]+/,""));
##replace comment
save.comment = save.comment.map(_ => _.replace(/console\.log/g, 'CONSOLE.LOG'));
##replace text
save.txt = save.txt.map(_ => _.replace(/console\.log/g, 'CONSOLE.LOG'));
##replace your code
m = m.replace(/console\.log/g, 'console.warn');
*/
// console.warn("##remove comment -> save.comment.fill('');");
save.comment.fill('');
return m;
}).replace(/\$\{save.(\w+)\[(\d+)\]\}/g, function(m, t, id) {
return save[t][id];
}).replace(/[\S\s]*/, function(m) {
console.log("result:", m);
// console.log("compare:", (context === m));
return m;
})
My English is not good, can someone help translate what I have written, I will be very grateful
Consider some problems
A.There may be strings in comments, or comments in strings, like
/*
const url="https://example.com/";
*/
const str = "i am s string and /*commet in string*/";
B. " or ' or ` in a string will be escaped with
like
const str = "my name is \"john\"";
const str2 = 'i am "john\'s" friend';
Combining the above multiple regex replaces will cause some problems
Consider regex find to the beginning part
" ' ` // /* <!--
use regex
(['"`]|\/[\*\/]|<!\-\-)
(['"`]|/[*/]|<!\-\-) result as \1
\1 is one of ' or " or
`
or /* or // or <!--
use If-Then-Else Conditionals in Regular Expressions
https://www.regular-expressions.info/conditional.html
(?:(?=(?<=\/\*))[\s\S]*?\*\/|(?=(?<=\/\/)).*|(?=(?<=<!\-\-))[\s\S]*?\-\->|[^\1]*?(?<!\\)\1)
if (?=(?<=\/\*))[\s\S]*?\*\/
(?=(?<=\/\*)) positive lookbehind (?<=\/\*) beacuse/*
It's a multi-line comment, so it should be followed by the latest one */
[\s\S]*?\*\/ match complete /*..\n..\n. */
elseif (?=(?<=\/\/)).*
(?=(?<=//)).* positive lookbehind
(?<=\/\/) catch // single line commet
.* match complete // any single commet
elseif (?=(?<=<!\-\-))[\s\S]*?\-\->
(?=(?<=<!--)) positive lookbehind (?<=<!\-\-) ,
[\s\S]*?\-\-> match complete
<!--..\n..\n. /*/*\-\->
else [^\1]*?(?<!\\)\1
Finally need to process the string
use regex [\s\S]*?\1
maybe the wrong result with "STR\" or 'STR"S\'
at [\s\S]*?we can use "positive lookbehind"
add this [\s\S]*?(?<!\\)\1 to filter escape quotes
end
Based on above attempts and using UltraEdit , mostly Abhishek Simon, I found this to work for inline comments and handles all of the characters within the comment.
(\s\/\/|$\/\/)[\w\s\W\S.]*
This matches comments at the start of the line or with a space before //
//public static final String LETTERS_WORK_FOLDER =
"/Letters/Generated/Work";
but not
"http://schemas.us.com.au/hub/'>" +
so it is only not good for something like
if(x){f(x)}//where f is some function
it just needs to be
if(x){f(x)} //where f is function
I have a string , in that I want to search the parentheses pair with proper nested and it must have some value inside it in javascript.
for example,
String = "#PriceMovement#-(#AssetProof#-(#TradeImpact#)/45)-#UninvestedCashImpact#"
In the above string all the variables are covered with # symbol.
As per the above statement TradeImpact will be divided by 45 first and remaining calculation has been made, if the user will enter like below then I should show error that wrong parentheses used(I cant do this with the count of opening and closing braces as the below string will also having equal start and close braces). Please help me to validate it thanks in advance.
String = "#PriceMovement#-(#AssetProof#-(#TradeImpact#))/45)-((#UninvestedCashImpact#)"
The easiest way is to replace variables with values and apply eval to the resulting string:
str = "#PriceMovement#-(#AssetProof#-(#TradeImpact#))/45)-((#UninvestedCashImpact#)"
values = {
PriceMovement: 1,
AssetProof: 2,
TradeImpact: 3,
UninvestedCashImpact: 5
}
try {
str = str.replace(/#(\w+)#/g, function($0, $1) {
return values[$1]
})
result = eval(str)
alert(result)
} catch(e) {
alert("Error: " + e)
}
This also catches other types of syntax errors, like invalid operators.
To check just brackets' nesting, replace (...) in a loop until there are no more matches. Then, check if the string contains an unpaired opening or closing bracket:
re = /\([^()]*\)/g
while(str.match(re))
str = str.replace(re, '')
if(str.match(/[()]/))
alert("INVALID NESTING")
I need to remove all JavaScript comments from a JavaScript source using the JavaScript RegExp object.
What I need is the pattern for the RegExp.
So far, I've found this:
compressed = compressed.replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, '');
This pattern works OK for:
/* I'm a comment */
or for:
/*
* I'm a comment aswell
*/
But doesn't seem to work for the inline:
// I'm an inline comment
I'm not quite an expert for RegEx and it's patterns, so I need help.
Also, I' would like to have a RegEx pattern which would remove all those HTML-like comments.
<!-- HTML Comment //--> or <!-- HTML Comment -->
And also those conditional HTML comments, which can be found in various JavaScript sources.
Thanks.
NOTE: Regex is not a lexer or a parser. If you have some weird edge case where you need some oddly nested comments parsed out of a string, use a parser. For the other 98% of the time this regex should work.
I had pretty complex block comments going on with nested asterisks, slashes, etc. The regular expression at the following site worked like a charm:
http://upshots.org/javascript/javascript-regexp-to-remove-comments
(see below for original)
Some modifications have been made, but the integrity of the original regex has been preserved. In order to allow certain double-slash (//) sequences (such as URLs), you must use back reference $1 in your replacement value instead of an empty string. Here it is:
/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm
// JavaScript:
// source_string.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1');
// PHP:
// preg_replace("/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/m", "$1", $source_string);
DEMO: https://regex101.com/r/B8WkuX/1
FAILING USE CASES: There are a few edge cases where this regex fails. An ongoing list of those cases is documented in this public gist. Please update the gist if you can find other cases.
...and if you also want to remove <!-- html comments --> use this:
/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*|<!--[\s\S]*?-->$/
(original - for historical reference only)
// DO NOT USE THIS - SEE ABOVE
/(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/gm
try this,
(\/\*[\w\'\s\r\n\*]*\*\/)|(\/\/[\w\s\']*)|(\<![\-\-\s\w\>\/]*\>)
should work :)
I have been putting togethor an expression that needs to do something similar.
the finished product is:
/(?:((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)|(\/\*(?:(?!\*\/).|[\n\r])*\*\/)|(\/\/[^\n\r]*(?:[\n\r]+|$))|((?:=|:)\s*(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))|((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)[gimy]?\.(?:exec|test|match|search|replace|split)\()|(\.(?:exec|test|match|search|replace|split)\((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))|(<!--(?:(?!-->).)*-->))/g
Scary right?
To break it down, the first part matches anything within single or double quotation marks
This is necessary to avoid matching quoted strings
((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)
the second part matches multiline comments delimited by /* */
(\/\*(?:(?!\*\/).|[\n\r])*\*\/)
The third part matches single line comments starting anywhere in the line
(\/\/[^\n\r]*(?:[\n\r]+|$))
The fourth through sixth parts matchs anything within a regex literal
This relies on a preceding equals sign or the literal being before or after a regex call
((?:=|:)\s*(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))
((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)[gimy]?\.(?:exec|test|match|search|replace|split)\()
(\.(?:exec|test|match|search|replace|split)\((?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/))
and the seventh which I originally forgot removes the html comments
(<!--(?:(?!-->).)*-->)
I had an issue with my dev environment issuing errors for a regex that broke a line, so I used the following solution
var ADW_GLOBALS = new Object
ADW_GLOBALS = {
quotations : /((["'])(?:(?:\\\\)|\\\2|(?!\\\2)\\|(?!\2).|[\n\r])*\2)/,
multiline_comment : /(\/\*(?:(?!\*\/).|[\n\r])*\*\/)/,
single_line_comment : /(\/\/[^\n\r]*[\n\r]+)/,
regex_literal : /(?:\/(?:(?:(?!\\*\/).)|\\\\|\\\/|[^\\]\[(?:\\\\|\\\]|[^]])+\])+\/)/,
html_comments : /(<!--(?:(?!-->).)*-->)/,
regex_of_doom : ''
}
ADW_GLOBALS.regex_of_doom = new RegExp(
'(?:' + ADW_GLOBALS.quotations.source + '|' +
ADW_GLOBALS.multiline_comment.source + '|' +
ADW_GLOBALS.single_line_comment.source + '|' +
'((?:=|:)\\s*' + ADW_GLOBALS.regex_literal.source + ')|(' +
ADW_GLOBALS.regex_literal.source + '[gimy]?\\.(?:exec|test|match|search|replace|split)\\(' + ')|(' +
'\\.(?:exec|test|match|search|replace|split)\\(' + ADW_GLOBALS.regex_literal.source + ')|' +
ADW_GLOBALS.html_comments.source + ')' , 'g'
);
changed_text = code_to_test.replace(ADW_GLOBALS.regex_of_doom, function(match, $1, $2, $3, $4, $5, $6, $7, $8, offset, original){
if (typeof $1 != 'undefined') return $1;
if (typeof $5 != 'undefined') return $5;
if (typeof $6 != 'undefined') return $6;
if (typeof $7 != 'undefined') return $7;
return '';
}
This returns anything captured by the quoted string text and anything found in a regex literal intact but returns an empty string for all the comment captures.
I know this is excessive and rather difficult to maintain but it does appear to work for me so far.
This works for almost all cases:
var RE_BLOCKS = new RegExp([
/\/(\*)[^*]*\*+(?:[^*\/][^*]*\*+)*\//.source, // $1: multi-line comment
/\/(\/)[^\n]*$/.source, // $2 single-line comment
/"(?:[^"\\]*|\\[\S\s])*"|'(?:[^'\\]*|\\[\S\s])*'/.source, // - string, don't care about embedded eols
/(?:[$\w\)\]]|\+\+|--)\s*\/(?![*\/])/.source, // - division operator
/\/(?=[^*\/])[^[/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[/\\]*)*?\/[gim]*/.source
].join('|'), // - regex
'gm' // note: global+multiline with replace() need test
);
// remove comments, keep other blocks
function stripComments(str) {
return str.replace(RE_BLOCKS, function (match, mlc, slc) {
return mlc ? ' ' : // multiline comment (replace with space)
slc ? '' : // single/multiline comment
match; // divisor, regex, or string, return as-is
});
}
The code is based on regexes from jspreproc, I wrote this tool for the riot compiler.
See http://github.com/aMarCruz/jspreproc
In plain simple JS regex, this:
my_string_or_obj.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ' ')
a bit simpler -
this works also for multiline - (<!--.*?-->)|(<!--[\w\W\n\s]+?-->)
Simple regex ONLY for multi-lines:
/\*((.|\n)(?!/))+\*/
The accepted solution does not capture all common use cases. See examples here: https://regex101.com/r/38dIQk/1.
The following regular expression should match JavaScript comments more reliably:
/(?:\/\*(?:[^\*]|\**[^\*\/])*\*+\/)|(?:\/\/[\S ]*)/g
For demonstration, visit the following link: https://regex101.com/r/z99Nq5/1/.
This is late to be of much use to the original question, but maybe it will help someone.
Based on #Ryan Wheale's answer, I've found this to work as a comprehensive capture to ensure that matches exclude anything found inside a string literal.
/(?:\r\n|\n|^)(?:[^'"])*?(?:'(?:[^\r\n\\']|\\'|[\\]{2})*'|"(?:[^\r\n\\"]|\\"|[\\]{2})*")*?(?:[^'"])*?(\/\*(?:[\s\S]*?)\*\/|\/\/.*)/g
The last group (all others are discarded) is based on Ryan's answer. Example here.
This assumes code is well structured and valid javascript.
Note: this has not been tested on poorly structured code which may or may not be recoverable depending on the javascript engine's own heuristics.
Note: this should hold for valid javascript < ES6, however, ES6 allows multi-line string literals, in which case this regex will almost certainly break, though that case has not been tested.
However, it is still possible to match something that looks like a comment inside a regex literal (see comments/results in the Example above).
I use the above capture after replacing all regex literals using the following comprehensive capture extracted from es5-lexer here and here, as referenced in Mike Samuel's answer to this question:
/(?:(?:break|case|continue|delete|do|else|finally|in|instanceof|return|throw|try|typeof|void|[+]|-|[.]|[/]|,|[*])|[!%&(:;<=>?[^{|}~])?(\/(?![*/])(?:[^\\\[/\r\n\u2028\u2029]|\[(?:[^\]\\\r\n\u2028\u2029]|\\(?:[^\r\n\u2028\u2029ux]|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}))+\]|\\(?:[^\r\n\u2028\u2029ux]|u[0-9A-Fa-f]{4}|x[0-9A-Fa-f]{2}))*\/[gim]*)/g
For completeness, see also this trivial caveat.
If you click on the link below you find a comment removal script written in regex.
These are 112 lines off code that work together also works with mootools and Joomla and drupal and other cms websites.
Tested it on 800.000 lines of code and comments. works fine.
This one also selects multiple parenthetical like ( abc(/nn/('/xvx/'))"// testing line") and comments that are between colons and protect them.
23-01-2016..! This is the code with the comments in it.!!!!
Click Here
I was looking for a quick Regex solution too, but none of the answers provided work 100%. Each one ends up breaking the source code in some way, mostly due to comments detected inside string literals. E.g.
var string = "https://www.google.com/";
Becomes
var string = "https:
For the benefit of those coming in from google, I ended up writing a short function (in Javascript) that achieves what the Regex couldn't do. Modify for whatever language you are using to parse Javascript.
function removeCodeComments(code) {
var inQuoteChar = null;
var inBlockComment = false;
var inLineComment = false;
var inRegexLiteral = false;
var newCode = '';
for (var i=0; i<code.length; i++) {
if (!inQuoteChar && !inBlockComment && !inLineComment && !inRegexLiteral) {
if (code[i] === '"' || code[i] === "'" || code[i] === '`') {
inQuoteChar = code[i];
}
else if (code[i] === '/' && code[i+1] === '*') {
inBlockComment = true;
}
else if (code[i] === '/' && code[i+1] === '/') {
inLineComment = true;
}
else if (code[i] === '/' && code[i+1] !== '/') {
inRegexLiteral = true;
}
}
else {
if (inQuoteChar && ((code[i] === inQuoteChar && code[i-1] != '\\') || (code[i] === '\n' && inQuoteChar !== '`'))) {
inQuoteChar = null;
}
if (inRegexLiteral && ((code[i] === '/' && code[i-1] !== '\\') || code[i] === '\n')) {
inRegexLiteral = false;
}
if (inBlockComment && code[i-1] === '/' && code[i-2] === '*') {
inBlockComment = false;
}
if (inLineComment && code[i] === '\n') {
inLineComment = false;
}
}
if (!inBlockComment && !inLineComment) {
newCode += code[i];
}
}
return newCode;
}
2019:
All other answers are incomplete and full of shortcomings. I take the time to write complete answer that WORK
function stripComments(code){
const savedText = [];
return code
.replace(/(['"`]).*?\1/gm,function (match) {
var i = savedText.push(match);
return (i-1)+'###';
})
// remove // comments
.replace(/\/\/.*/gm,'')
// now extract all regex and save them
.replace(/\/[^*\n].*\//gm,function (match) {
var i = savedText.push(match);
return (i-1)+'###';
})
// remove /* */ comments
.replace(/\/\*[\s\S]*\*\//gm,'')
// remove <!-- --> comments
.replace(/<!--[\s\S]*-->/gm, '')
.replace(/\d+###/gm,function(match){
var i = Number.parseInt(match);
return savedText[i];
})
}
var cleancode = stripComments(stripComments.toString())
console.log(cleancode)
Other answers not working on samples code like that:
// won't execute the creative code ("Can't execute code form a freed script"),
navigator.userAgent.match(/\b(MSIE |Trident.*?rv:|Edge\/)(\d+)/);
function stripComments(code){
const savedText = [];
return code
// extract strings and regex
.replace(/(['"`]).*?\1/gm,function (match) {
savedText.push(match);
return '###';
})
// remove // comments
.replace(/\/\/.*/gm,'')
// now extract all regex and save them
.replace(/\/[^*\n].*\//gm,function (match) {
savedText.push(match);
return '###';
})
// remove /* */ comments
.replace(/\/\*[\s\S]*\*\//gm,'')
// remove <!-- --> comments
.replace(/<!--[\s\S]*-->/gm, '')
/*replace \ with \\ so we not lost \b && \t*/
.replace(/###/gm,function(){
return savedText.shift();
})
}
var cleancode = stripComments(stripComments.toString())
console.log(cleancode)
for /**/ and //
/(?:(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:(?<!\:|\\\|\')\/\/.*))/gm
I wonder if this was a trick question given by
a professor to students. Why? Because it seems
to me it is IMPOSSIBLE to do this, with
Regular Expressions, in the general case.
Your (or whoever's code it is) can contain
valid JavaScript like this:
let a = "hello /* ";
let b = 123;
let c = "world */ ";
Now if you have a regexp which removes everything
between a pair of /* and */, it would break the code
above, it would remove the executable code in the
middle as well.
If you try to devise a regexp that would not
remove comments which contain quotes then
you cannot remove such comments. That applies
to single-quote, double-quotes and back-quotes.
You can not remove (all) comments with Regular
Expressions in JavaScript, it seems to me,
maybe someone can point out a way how to do
it for the case above.
What you can do is build a small parser which
goes through the code character by character
and knows when it is inside a string and when
it is inside a comment, and when it is inside
a comment inside a string and so on.
I'm sure there are good open source JavaScript
parsers that can do this. Maybe some of the
packaging and minifying tools can do this for
you as well.
For block comment:
https://regex101.com/r/aepSSj/1
Matches slash character (the \1) only if slash character is followed by asterisk.
(\/)(?=\*)
maybe followed by another asterisk
(?:\*)
followed by first group of match, or zero or more times from something...maybe, without remember the match but capture as a group.
((?:\1|[\s\S])*?)
followed by asterisk and first group
(?:\*)\1
For block and/or inline comment:
https://regex101.com/r/aepSSj/2
where | mean or and (?=\/\/(.*)) capture anything after any //
or https://regex101.com/r/aepSSj/3
to capture the third part too
all in: https://regex101.com/r/aepSSj/8
DEMO: https://onecompiler.com/javascript/3y825u3d5
const context = `
<html>
<script type="module">
/* I'm a comment */
/*
* I'm a comment aswell url="https://example.com/";
*/
var re = /\\/*not a comment!*/;
var m = /\\//.test("\"not a comment!\"");
var re = /"/; // " thiscommentishandledasascode!
const s1 = "multi String \\
\\"double quote\\" \\
// single commet in str \\
/* multiple lines commet in str \\
secend line */ \\
last line";
const s2 = 's2"s';
const url = "https://example.com/questions/5989315/";
let a = "hello /* ";
let b = 123;
let c = "world */ ";
//public static final String LETTERS_WORK_FOLDER = "/Letters/Generated/Work";
console.log(/*comment in
console.log*/ "!message at console.log");
function displayMsg( // the end comment
/*commet arg1*/ a, ...args) {
console.log("Hello World!", a, ...args)
}
<\/script>
<body>
<!-- HTML Comment //--> or <!-- HTML Comment -->
<!--
function displayMsg() {
alert("Hello World!")
}
//-->
</body>
</html>
`;
console.log("before:\n" + context);
console.log("<".repeat(100));
const save = {'txt':[], 'comment':[], 'regex': []};
const context2 =
context.replace(/(['"`]|\/[\*\/]{0,1}|<!\-\-)(?:(?=(?<=\/\*))[\s\S]*?\*\/|(?=(?<=\/\/)).*|(?=(?<=<!\-\-))[\s\S]*?\-\->|(?=(?<=[\s\=]\/)).+?(?<!\\)\/|(?=(?<=['"`]))[\s\S]*?(?<!\\)\1)/g,
function (m) {
const t = (m[0].match(/["'`]/) && 'txt') || (m.match(/^(\/\/|\/\*|<)/) && 'comment') || 'regex';
save[t].push(m);
return '${save.'+t+'['+(save[t].length - 1)+']}';
}).replace(/[\S\s]*/, function(m) {
console.log("watch:\n"+m);
console.log(">".repeat(100));
/*
##remove comment
save.comment = save.comment.map(_ => _.replace(/[\S\s]+/,""));
##replace comment
save.comment = save.comment.map(_ => _.replace(/console\.log/g, 'CONSOLE.LOG'));
##replace text
save.txt = save.txt.map(_ => _.replace(/console\.log/g, 'CONSOLE.LOG'));
##replace your code
m = m.replace(/console\.log/g, 'console.warn');
*/
// console.warn("##remove comment -> save.comment.fill('');");
save.comment.fill('');
return m;
}).replace(/\$\{save.(\w+)\[(\d+)\]\}/g, function(m, t, id) {
return save[t][id];
}).replace(/[\S\s]*/, function(m) {
console.log("result:", m);
// console.log("compare:", (context === m));
return m;
})
My English is not good, can someone help translate what I have written, I will be very grateful
Consider some problems
A.There may be strings in comments, or comments in strings, like
/*
const url="https://example.com/";
*/
const str = "i am s string and /*commet in string*/";
B. " or ' or ` in a string will be escaped with
like
const str = "my name is \"john\"";
const str2 = 'i am "john\'s" friend';
Combining the above multiple regex replaces will cause some problems
Consider regex find to the beginning part
" ' ` // /* <!--
use regex
(['"`]|\/[\*\/]|<!\-\-)
(['"`]|/[*/]|<!\-\-) result as \1
\1 is one of ' or " or
`
or /* or // or <!--
use If-Then-Else Conditionals in Regular Expressions
https://www.regular-expressions.info/conditional.html
(?:(?=(?<=\/\*))[\s\S]*?\*\/|(?=(?<=\/\/)).*|(?=(?<=<!\-\-))[\s\S]*?\-\->|[^\1]*?(?<!\\)\1)
if (?=(?<=\/\*))[\s\S]*?\*\/
(?=(?<=\/\*)) positive lookbehind (?<=\/\*) beacuse/*
It's a multi-line comment, so it should be followed by the latest one */
[\s\S]*?\*\/ match complete /*..\n..\n. */
elseif (?=(?<=\/\/)).*
(?=(?<=//)).* positive lookbehind
(?<=\/\/) catch // single line commet
.* match complete // any single commet
elseif (?=(?<=<!\-\-))[\s\S]*?\-\->
(?=(?<=<!--)) positive lookbehind (?<=<!\-\-) ,
[\s\S]*?\-\-> match complete
<!--..\n..\n. /*/*\-\->
else [^\1]*?(?<!\\)\1
Finally need to process the string
use regex [\s\S]*?\1
maybe the wrong result with "STR\" or 'STR"S\'
at [\s\S]*?we can use "positive lookbehind"
add this [\s\S]*?(?<!\\)\1 to filter escape quotes
end
Based on above attempts and using UltraEdit , mostly Abhishek Simon, I found this to work for inline comments and handles all of the characters within the comment.
(\s\/\/|$\/\/)[\w\s\W\S.]*
This matches comments at the start of the line or with a space before //
//public static final String LETTERS_WORK_FOLDER =
"/Letters/Generated/Work";
but not
"http://schemas.us.com.au/hub/'>" +
so it is only not good for something like
if(x){f(x)}//where f is some function
it just needs to be
if(x){f(x)} //where f is function