RegEx for match/replacing JavaScript comments (both multiline and inline) - javascript

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

Related

Redundant if statement?

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.

get all single and multiline comment in javascript [duplicate]

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

Remove special character from the starting of a string and search # symbol.in javascript

I want to remove special characters from the starting of the string only.
i.e, if my string is like {abc#xyz.com then I want to remove the { from the starting. The string shoould look like abc#xyz.com
But if my string is like abc{#xyz.com then I want to retain the same string as it is ie., abc{#xyz.com.
Also I want to check that if my string has # symbol present or not. If it is present then OK else show a message.
The following demonstrates what you specified (or it's close):
var pat = /^[^a-z0-9]*([a-z0-9].*?#.*?$)/i; //pattern for optional non-alphabetic start followed by alphabetic, followed by '#' somewhere
var testString = "{abc#xyz.com"; //Try with {abcxyz.com for alert
arr = pat.exec(testString);
var adjustedString;
if (arr != null) { adjustedString = arr[1]; } //The potentially adjustedString (chopped off non-alphabetic start) will be in capture group 1
else { adjustedString = ""; alert(testString + " does not conform to pattern"); }
adjustedString;
I have used two separate regex objects to achieve what you require .It checks for both the conditions in the string.I know its not very efficient but it will serve your purpose.
var regex = new RegExp(/(^{)/);
var regex1 = new RegExp(/(^[^#]*$)/);
var str = "abc#gmail.com";
if(!regex1.test(str)){
if(regex.test(str))
alert("Bracket found at the beginning")
else
alert("Bracket not found at the beginning")
}
else{
alert("doesnt contain #");
}
Hope this helps

Regex, grab only one instance of each letter

I have a paragraph that's broken up into an array, split at the periods. I'd like to perform a regex on index[i], replacing it's contents with one instance of each letter that index[i]'s string value has.
So; index[i]:"This is a sentence" would return --> index[i]:"thisaenc"
I read this thread. But i'm not sure if that's what i'm looking for.
Not sure how to do this in regex, but here's a very simple function to do it without using regex:
function charsInString(input) {
var output='';
for(var pos=0; pos<input.length; pos++) {
char=input.charAt(pos).toLowerCase();
if(output.indexOf(char) == -1 && char != ' ') {output+=char;}
}
return output;
}
alert(charsInString('This is a sentence'));
As I'm pretty sure what you need cannot be achieved using a single regular expression, I offer a more general solution:
// collapseSentences(ary) will collapse each sentence in ary
// into a string containing its constituent chars
// #param {Array} the array of strings to collapse
// #return {Array} the collapsed sentences
function collapseSentences(ary){
var result=[];
ary.forEach(function(line){
var tmp={};
line.toLowerCase().split('').forEach(function(c){
if(c >= 'a' && c <= 'z') {
tmp[c]++;
}
});
result.push(Object.keys(tmp).join(''));
});
return result;
}
which should do what you want except that the order of characters in each sentence cannot be guaranteed to be preserved, though in most cases it is.
Given:
var index=['This is a sentence','This is a test','this is another test'],
result=collapseSentences(index);
result contains:
["thisaenc","thisae", "thisanoer"]
(\w)(?<!.*?\1)
This yields a match for each of the right characters, but as if you were reading right-to-left instead.
This finds a word character, then looks ahead for the character just matched.
Nevermind, i managed:
justC = "";
if (color[i+1].match(/A/g)) {justC += " L_A";}
if (color[i+1].match(/B/g)) {justC += " L_B";}
if (color[i+1].match(/C/g)) {justC += " L_C";}
if (color[i+1].match(/D/g)) {justC += " L_D";}
if (color[i+1].match(/E/g)) {justC += " L_E";}
else {color[i+1] = "L_F";}
It's not exactly what my question may have lead to belive is what i wanted, but the printout for this is what i was after, for use in a class: <span class="L_A L_C L_E"></span>
How about:
var re = /(.)((.*?)\1)/g;
var str = 'This is a sentence';
x = str.toLowerCase();
x = x.replace(/ /g, '');
while(x.match(re)) {
x=x.replace(re, '$1$3');
}
I don't think this can be done in one fell regex swoop. You are going to need to use a loop.
While my example was not written in your language of choice, it doesn't seem to use any regex features not present in javascript.
perl -e '$foo="This is a sentence"; while ($foo =~ s/((.).*?)\2/$1/ig) { print "<$1><$2><$foo>\n"; } print "$foo\n";'
Producing:
This aenc

Return string without trailing slash

I have two variables:
site1 = "www.somesite.com";
site2 = "www.somesite.com/";
I want to do something like this
function someFunction(site)
{
// If the var has a trailing slash (like site2),
// remove it and return the site without the trailing slash
return no_trailing_slash_url;
}
How do I do this?
Try this:
function someFunction(site)
{
return site.replace(/\/$/, "");
}
ES6 / ES2015 provides an API for asking whether a string ends with something, which enables writing a cleaner and more readable function.
const stripTrailingSlash = (str) => {
return str.endsWith('/') ?
str.slice(0, -1) :
str;
};
function stripTrailingSlash(str) {
if(str.substr(-1) === '/') {
return str.substr(0, str.length - 1);
}
return str;
}
Note: IE8 and older do not support negative substr offsets. Use str.length - 1 instead if you need to support those ancient browsers.
I'd use a regular expression:
function someFunction(site)
{
// if site has an end slash (like: www.example.com/),
// then remove it and return the site without the end slash
return site.replace(/\/$/, '') // Match a forward slash / at the end of the string ($)
}
You'll want to make sure that the variable site is a string, though.
Based on #vdegenne 's answer... how to strip:
Single trailing slash:
theString.replace(/\/$/, '');
Single or consecutive trailing slashes:
theString.replace(/\/+$/g, '');
Single leading slash:
theString.replace(/^\//, '');
Single or consecutive leading slashes:
theString.replace(/^\/+/g, '');
Single leading and trailing slashes:
theString.replace(/^\/|\/$/g, '')
Single or consecutive leading and trailing slashes:
theString.replace(/^\/+|\/+$/g, '')
To handle both slashes and backslashes, replace instances of \/ with [\\/]
I know the question is about trailing slashes but I found this post during my search for trimming slashes (both at the tail and head of a string literal), as people would need this solution I am posting one here :
'///I am free///'.replace(/^\/+|\/+$/g, ''); // returns 'I am free'
UPDATE:
as #Stephen R mentioned in the comments, if you want to remove both slashes and backslashes both at the tail and the head of a string literal, you would write :
'\/\\/\/I am free\\///\\\\'.replace(/^[\\/]+|[\\/]+$/g, '') // returns 'I am free'
This snippet is more accurate:
str.replace(/^(.+?)\/*?$/, "$1");
It not strips / strings, as it's a valid url.
It strips strings with multiple trailing slashes.
function stripTrailingSlash(text) {
return text
.split('/')
.filter(Boolean)
.join('/');
}
another solution.
Here a small url example.
var currentUrl = location.href;
if(currentUrl.substr(-1) == '/') {
currentUrl = currentUrl.substr(0, currentUrl.length - 1);
}
log the new url
console.log(currentUrl);
The easiest way I know of is this:
function stripTrailingSlash(str){
if(str.charAt(str.length-1) == "/"){ str = str.substr(0, str.length - 1);}
return str
}
Updates ES2015 version.
const stripTrailingSlash = str=>str.charAt(str.length-1)=="/"?str.substr(0,str.length-1):str;
This will then check for a / on the end and if it's there, remove it. If it's not, it will return your string as it was.
Fixed the calculation for zero-based index on the string.
EDIT:
As there was a comment to one response there are now more doing the same thing do not use sub string for a comparison, you're creating a whole new string in memory (at the low level) when you can use charAt to get a single char a lot less memory to do your comparison, Javascript is still JIT and can't do the optimisations to the level any lang going though a compiler can, it won't fix this for you.
In case you are working with URLs then you can use the built-in URL class
const url = new URL('https://foo.bar/');
console.log(url.toString()); // https://foo.bar
function someFunction(site) {
if (site.indexOf('/') > 0)
return site.substring(0, site.indexOf('/'));
return site;
}

Categories