Strip block comments: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Added PHP solution)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(29 intermediate revisions by 21 users not shown)
Line 1:
{{task|Text processing}}
[[Category:String manipulation]]
[[Category:Strings]]
 
A block comment begins with a   ''beginning delimiter''   and ends with a   ''ending delimiter'',   including the delimiters.   These delimiters are often multi-character sequences.
Line 10 ⟶ 11:
Your demos should at least handle simple, non-nested and multi-line block comment delimiters.
 
The block comment delimiters are the two-character sequencesequences:
:::* &nbsp; &nbsp; <big><big> '''/*''' </big></big> &nbsp; &nbsp; (beginning delimiter)
:::* &nbsp; &nbsp; <big><big> '''*/''' </big></big> &nbsp; &nbsp; (ending delimiter)
Line 39 ⟶ 40:
 
 
{{Template:Strings}}
;Related task:
* &nbsp; [[Strip comments from a string]]
<br><br>
 
=={{header|11l}}==
<syntaxhighlight lang="11l">F strip_comments(s, b_delim = ‘/*’, e_delim = ‘*/’)
V r = ‘’
V i = 0
L
V? p = s.find(b_delim, i)
I p == N
L.break
r ‘’= s[i .< p]
V? e = s.find(e_delim, p + b_delim.len)
assert(e != N)
i = e + e_delim.len
r ‘’= s[i..]
R r
 
V text = ‘
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}’
 
print(strip_comments(text))</syntaxhighlight>
 
{{out}}
<pre>
 
 
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}
</pre>
 
=={{header|Ada}}==
strip.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Strings.Fixed;
with Ada.Strings.Unbounded;
with Ada.Text_IO;
Line 137 ⟶ 186:
end loop;
Ada.Text_IO.Close (File => File);
end Strip;</langsyntaxhighlight>
output:
<pre>
Line 155 ⟶ 204:
function something() {
}</pre>
 
=={{header|ALGOL W}}==
Handles non-nested block comments, the start and end delimiters are specified as parameters. Comments inside string-literals are retained. The string quote and escape characters are specified as parameters.
<syntaxhighlight lang="algolw">begin
% strips block comments from a source %
% the source is read from standard input and the result written to %
% standard output, The comment start text is in cStart and the ending %
% is in cEnd. %
% As strings are fixed length in Algol W, the first space in cStart/cEnd %
% is assumed to terminate the delimiter, i.e. the comment start/end %
% delimiters cannot contain spaces. %
% If non-blank, quote1 and quote2 are the string quote characters. %
% If escape is non-blank it indicates that quotes can be embedded in %
% string literals by preceding them with escape (as in C, java, etc.). %
procedure stripBlockComments( string(32) value cStart, cEnd
; string(1) value quote1, quote2, escape
) ;
begin
integer columnNumber, lineWidth;
string(256) line;
string(1) currChar;
string(1) newlineChar;
% gets the next source character %
procedure nextChar ;
begin
if columnNumber = lineWidth then begin
currChar := newlineChar;
columnNumber := columnNumber + 1
end
else if columnNumber > lineWidth then begin
readcard( line );
lineWidth := 256;
while lineWidth > 0 and line( lineWidth - 1 // 1 ) = " " do lineWidth := lineWidth - 1;
columnNumber := 1;
currChar := line( 0 // 1 )
end
else begin
currChar := line( columnNumber // 1 );
columnNumber := columnNumber + 1
end
end nextChar ;
% copy the current character and get the next %
procedure copyAndNext ;
begin
if currChar = newlineChar then write()
else writeon( currChar );
nextChar
end copyAndNext ;
% skips the current character and gets the next %
procedure skipAndNext ;
begin
if currChar not = newlineChar then currChar := " ";
copyAndNext
end skipAndNext ;
% handle a string literal %
procedure stringLiteral( string(1) value quote, escape ) ;
begin
copyAndNext;
while currChar not = quote and not XCPNOTED(ENDFILE) do begin
if escape <> " " and currChar = escape then copyAndNext;
if not XCPNOTED(ENDFILE) then copyAndNext
end while_have_more_string ;
if currChar = quote then copyAndNext
end stringLiteral ;
% returns true if the line continues with the specified text %
% false if not. %
logical procedure remainingLineStartsWith ( string(32) value text ) ;
begin
logical haveText;
integer lPos, wPos;
haveText := currChar = text( 0 // 1 );
lPos := columnNumber;
wPos := 1;
while haveText and wPos <= 32 and text( wPos // 1 ) not = " " do begin
if lPos >= lineWidth then begin
% past the end of the line %
haveText := false
end
else begin
% still have text on the line %
haveText := line( lPos // 1 ) = text( wPos // 1 );
wPos := wPos + 1;
lPos := lPos + 1;
end if_past_end_of_line_
end while_have_text_and_more_text ;
haveText
end remainingLineStartsWith ;
% skips the number of leading non-blank characters in the delimiter %
procedure skipDelimiter( string(32) value delimiter ) ;
begin
integer dPos;
dPos := 0;
while dPos < 32 and not XCPNOTED(ENDFILE) and delimiter( dPos // 1 ) not = " " do begin
dPos := dPos + 1;
skipAndNext
end while_not_at_end_of_delimiter
end skipDelimiter ;
newlineChar := code( 10 );
lineWidth := 0;
columnNumber := lineWidth + 1;
currChar := " ";
% allow the program to continue after reaching end-of-file %
ENDFILE := EXCEPTION( false, 1, 0, false, "EOF" );
% get the first source character %
nextChar;
% strip the comments %
while not XCPNOTED(ENDFILE) do begin
if currChar = " " then copyAndNext
else if remainingLineStartsWith( cStart ) then begin
% have a comment %
skipDelimiter( cStart );
while not remainingLineStartsWith( cEnd ) and not XCPNOTED(ENDFILE) do skipAndNext;
skipDelimiter( cEnd )
end
else if currChar = quote1 then stringLiteral( quote1, escape )
else if currChar = quote2 then stringLiteral( quote2, escape )
else copyAndNext
end while_not_at_eof
end stripBlockComments ;
% text stripBlockComments for C-style source %
stripBlockComments( "/*", "*/", """", "'", "\" )
end.</syntaxhighlight>
{{out}}
<pre>
function subroutine() {
a = b + c ;
}
function something() {
}
</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">code =
(
/**
Line 183 ⟶ 373:
closeC:=RegExReplace(closeC,"(\*|\^|\?|\\|\+|\.|\!|\{|\}|\[|\]|\$|\|)","\$0")
;Display final result
MsgBox % sCode := RegExReplace(code,"s)(" . openC . ").*?(" . closeC . ")")</langsyntaxhighlight>
<pre>
 
Line 194 ⟶ 384:
function something() {
}</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f STRIP_BLOCK_COMMENTS.AWK filename
# source: https://www.gnu.org/software/gawk/manual/gawk.html#Plain-Getline
# Remove text between /* and */, inclusive
{ while ((start = index($0,"/*")) != 0) {
out = substr($0,1,start-1) # leading part of the string
rest = substr($0,start+2) # ... */ ...
while ((end = index(rest,"*/")) == 0) { # is */ in trailing part?
if (getline <= 0) { # get more text
printf("unexpected EOF or error: %s\n",ERRNO) >"/dev/stderr"
exit
}
rest = rest $0 # build up the line using string concatenation
}
rest = substr(rest,end+2) # remove comment
$0 = out rest # build up the output line using string concatenation
}
printf("%s\n",$0)
}
END {
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
 
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}
 
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> infile$ = "C:\sample.c"
outfile$ = "C:\stripped.c"
Line 234 ⟶ 461:
CLOSE #infile%
CLOSE #outfile%
ENDPROC</langsyntaxhighlight>
Output file:
<pre>
Line 249 ⟶ 476:
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
Line 301 ⟶ 528:
free(s);
return 0;
}</langsyntaxhighlight>
;Usage:
Specify an input file via the first command line argument, and optionally specify comment opening and closing delimiters with the next two args, or defaults of /* and */ are assumed.
Line 317 ⟶ 544:
 
</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using System;
 
class Program
{
private static string BlockCommentStrip(string commentStart, string commentEnd, string sampleText)
{
while (sampleText.IndexOf(commentStart) > -1 && sampleText.IndexOf(commentEnd, sampleText.IndexOf(commentStart) + commentStart.Length) > -1)
{
int start = sampleText.IndexOf(commentStart);
int end = sampleText.IndexOf(commentEnd, start + commentStart.Length);
sampleText = sampleText.Remove(
start,
(end + commentEnd.Length) - start
);
}
return sampleText;
}
}</syntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <string>
#include <iostream>
#include <iterator>
Line 342 ⟶ 589:
return 1 ;
}
}</langsyntaxhighlight>
Output:
<pre>
Line 356 ⟶ 603:
}
</pre>
 
=={{header|C sharp|C#}}==
<lang Csharp>using System;
 
class Program
{
private static string BlockCommentStrip(string commentStart, string commentEnd, string sampleText)
{
while (sampleText.IndexOf(commentStart) > -1 && sampleText.IndexOf(commentEnd, sampleText.IndexOf(commentStart) + commentStart.Length) > -1)
{
int start = sampleText.IndexOf(commentStart);
int end = sampleText.IndexOf(commentEnd, start + commentStart.Length);
sampleText = sampleText.Remove(
start,
(end + commentEnd.Length) - start
);
}
return sampleText;
}
}</lang>
 
=={{header|Clojure}}==
<langsyntaxhighlight Clojurelang="clojure">(defn comment-strip [txt & args]
(let [args (conj {:delim ["/*" "*/"]} (apply hash-map args)) ; This is the standard way of doing keyword/optional arguments in Clojure
[opener closer] (:delim args)]
Line 389 ⟶ 616:
(= (apply str hdtxt) closer) (recur out resttxt (dec delim-count))
(= delim-count 0)(recur (str out (first txt)) (rest txt) delim-count)
true (recur out (rest txt) delim-count))))))</langsyntaxhighlight>
<pre>user> (comment-strip "This /* is */ some /* /* /* */ funny */ */ text")
hdtxt= Th resttxt=is /* is */ some /* /* /* */ funny */ */ text out= txt=This /* is */ some /* /* /* */ funny */ */ text delim-count=0
Line 434 ⟶ 661:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.algorithm, std.regex;
 
string[2] separateComments(in string txt,
Line 522 ⟶ 749:
 
showResults(ex2, separateComments(ex2, `#|;`, `[\n\r]|$`));
}</langsyntaxhighlight>
{{out}}
<pre>===Original text:
Line 578 ⟶ 805:
===The stripped comments:
# and bananas; and bananas </pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
program Strip_block_comments;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
function BlockCommentStrip(commentStart, commentEnd, sampleText: string): string;
begin
while ((sampleText.IndexOf(commentStart) > -1) and (sampleText.IndexOf(commentEnd,
sampleText.IndexOf(commentStart) + commentStart.Length) > -1)) do
begin
var start := sampleText.IndexOf(commentStart);
var _end := sampleText.IndexOf(commentEnd, start + commentStart.Length);
sampleText := sampleText.Remove(start, (_end + commentEnd.Length) - start);
end;
Result := sampleText;
end;
 
const
test = '/**' + #10 + '* Some comments' + #10 +
'* longer comments here that we can parse.' + #10 + '*' + #10 + '* Rahoo ' +
#10 + '*/' + #10 + 'function subroutine() {' + #10 +
'a = /* inline comment */ b + c ;' + #10 + '}' + #10 +
'/*/ <-- tricky comments */' + #10 + '' + #10 + '/**' + #10 +
'* Another comment.' + #10 + '*/' + #10 + 'function something() {' + #10 + '}';
 
begin
 
writeln(BlockCommentStrip('/*', '*/', test));
readln;
end.</syntaxhighlight>
{{out}}
<pre>
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight lang="easylang">
subr process
i = 1
while i <= len s$
if inc = 0 and substr s$ i 2 = "/*"
inc = 1
i += 1
elif inc = 1 and substr s$ i 2 = "*/"
inc = 0
i += 1
elif inc = 0
write substr s$ i 1
.
i += 1
.
if inc = 0
print ""
.
.
repeat
s$ = input
until error = 1
process
.
input_data
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
</syntaxhighlight>
 
 
=={{header|F_Sharp|F#}}==
Using .NET's regex counter feature to match nested comments.
If comments here are nested, they have to be correctly balanced.
<syntaxhighlight lang="fsharp">open System
open System.Text.RegularExpressions
 
let balancedComments opening closing =
new Regex(
String.Format("""
{0} # An outer opening delimiter
(?> # efficiency: no backtracking here
{0} (?<LEVEL>) # An opening delimiter, one level down
|
{1} (?<-LEVEL>) # A closing delimiter, one level up
|
(?! {0} | {1} ) . # With negative lookahead: Anything but delimiters
)* # As many times as we see these
(?(LEVEL)(?!)) # Fail, unless on level 0 here
{1} # Outer closing delimiter
""", Regex.Escape(opening), Regex.Escape(closing)),
RegexOptions.IgnorePatternWhitespace ||| RegexOptions.Singleline)
 
[<EntryPoint>]
let main args =
let sample = """
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
* /* nested balanced
*/ */
function something() {
}
"""
let balancedC = balancedComments "/*" "*/"
printfn "%s" (balancedC.Replace(sample, ""))
0</syntaxhighlight>
Output
<pre>
 
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}
</pre>
 
=={{header|Factor}}==
===Regexp implementation===
<syntaxhighlight lang="factor">
: strip-block-comments ( string -- string )
R/ /\*.*?\*\// "" re-replace ;
</syntaxhighlight>
===Manual implementation===
<syntaxhighlight lang="factor">
USING: kernel io accessors strings math sequences locals
io.streams.string multiline prettyprint ;
 
IN: strip-block-comments
 
TUPLE: comment-state
{ is-in-comment initial: f }
{ delim-start string initial: "/*" }
{ delim-end string initial: "*/" }
{ chars-matched integer initial: 0 } ;
 
: set-delims ( cmnt-st start end -- cmnt-st )
[ >>delim-start ] dip
>>delim-end ;
 
: target-delim ( cmnt-st -- string )
dup is-in-comment>>
[ delim-end>> ]
[ delim-start>> ] if ;
 
: target-char ( cmnt-st -- ch )
dup chars-matched>> swap ! ( cmnt-st -- n cmnt-st )
target-delim nth ;
 
: got-delim? ( cmnt-st -- ? )
[ target-delim length ] keep
chars-matched>> <= ;
 
: update-is-in-comment ( cmnt-st -- cmnt-st )
dup got-delim?
[ [ not ] change-is-in-comment 0 >>chars-matched ]
when ;
 
: matched-chars ( cmnt-st -- string )
[ target-delim ] [ chars-matched>> ] bi
0 swap rot <slice> ;
 
:: process-char ( cmnt-st ch -- cmnt-st )
cmnt-st update-is-in-comment
target-char ch =
[
cmnt-st [ 1 + ] change-chars-matched
update-is-in-comment
]
[
cmnt-st is-in-comment>>
[ cmnt-st matched-chars >string write ch write1 ] unless
cmnt-st
] if ;
 
: process-string ( cmnt-st string -- cmnt-st )
[ process-char ] each ;
 
: strip-block-comments ( string -- string )
[ comment-state new swap process-string drop ]
with-string-writer ;
 
: strip-block-comments-with-delims ( string start end -- string )
[ comment-state new -rot set-delims swap process-string drop ] with-string-writer ;
 
CONSTANT: sample-text [[
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
]]
 
: test-strip-block-comments ( -- )
sample-text strip-block-comments write
"foo(bar)" "(" ")" strip-block-comments-with-delims "foo" assert= ;
 
MAIN: test-strip-block-comments
</syntaxhighlight>
 
=={{header|Fortran}}==
Line 593 ⟶ 1,063:
A feature of Fortran's character comparison is that trailing spaces are ignored, so that "x " and "x " and "x" are all deemed equal. Unfortunate choices of starting and ending delimiter texts can be made if they contain characters in common.
 
<syntaxhighlight lang="fortran">
<lang Fortran>
SUBROUTINE UNBLOCK(THIS,THAT) !Removes block comments bounded by THIS and THAT.
Copies from file INF to file OUT, record by record, except skipping null output records.
Line 677 ⟶ 1,147:
 
END !All open files are closed on exit..
</syntaxhighlight>
</lang>
 
Output: the report is "16 read, 8 written." And in the output file appears...
Line 712 ⟶ 1,182:
F90 allows the syntax END SUBROUTINE UNBLOCK (and insists on it within a MODULE) but F77 does not, otherwise the statement could have been <code>CALL UNBLOCK("SUBROUTINE","END SUBROUTINE")</code> which would be rather more structured.
 
=={{header|F_Sharp|F#}}==
Using .NET's regex counter feature to match nested comments.
If comments here are nested, they have to be correctly balanced.
<lang fsharp>open System
open System.Text.RegularExpressions
 
=={{header|FreeBASIC}}==
let balancedComments opening closing =
{{trans|Liberty BASIC}}
new Regex(
<syntaxhighlight lang="freebasic">Const CRLF = Chr(13) + Chr(10)
String.Format("""
{0} # An outer opening delimiter
(?> # efficiency: no backtracking here
{0} (?<LEVEL>) # An opening delimiter, one level down
|
{1} (?<-LEVEL>) # A closing delimiter, one level up
|
(?! {0} | {1} ) . # With negative lookahead: Anything but delimiters
)* # As many times as we see these
(?(LEVEL)(?!)) # Fail, unless on level 0 here
{1} # Outer closing delimiter
""", Regex.Escape(opening), Regex.Escape(closing)),
RegexOptions.IgnorePatternWhitespace ||| RegexOptions.Singleline)
 
Function stripBlocks(text As String, first As String, last As String) As String
[<EntryPoint>]
Dim As String temp = ""
let main args =
For i As Integer = 1 To Len(text) - Len(first)
let sample = """
If Mid(text, i, Len(first)) = first Then
/**
i += Len(first)
* Some comments
* longer comments here that we can parse. Do
If Mid(text, i, 2) = CRLF Then temp &= CRLF
*
* Rahoo i += 1
Loop Until (Mid(text, i, Len(last)) = last) Or (i = Len(text) - Len(last))
*/
function subroutine i += Len(last) {-1
a = /* inline comment */ b + c ;Else
temp &= Mid(text, i, 1)
}
/*/ <-- tricky comments */End If
Next i
Return temp
End Function
 
Dim As String source
/**
source = " /**" + CRLF + _
* Another comment.
" * Some comments" + CRLF + _
* /* nested balanced
" * longer comments here that we can parse." + CRLF + _
*/ */
" *" + CRLF + _
function something() {
" * Rahoo " + CRLF + _
}
" */"" + CRLF + _
" function subroutine() {" + CRLF + _
let balancedC = balancedComments "/*" "*/"
" a = /* inline comment */ b + c ;" + CRLF + _
printfn "%s" (balancedC.Replace(sample, ""))
" }" + CRLF + _
0</lang>
" /*/ <-- tricky comments */" + CRLF + _
Output
"" + CRLF + _
" /**" + CRLF + _
" * Another comment." + CRLF + _
" */" + CRLF + _
" function something() {" + CRLF + _
" }" + CRLF
 
Print stripBlocks(source, "/*", "*/")
Sleep</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Liberty BASIC.
 
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}
</pre>
 
=={{header|Go}}==
For the extra credit: No optional parameters in Go, but documented below is an efficient technique for letting the caller specify the delimiters.
<langsyntaxhighlight lang="go">package main
 
import (
Line 826 ⟶ 1,284:
function something() {
}`))
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">def code = """
/**
* Some comments
Line 848 ⟶ 1,306:
"""
 
println ((code =~ "(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)").replaceAll(''))</langsyntaxhighlight>
 
=={{header|Haskell}}==
THE FOLLOWING SOLUTION IS WRONG, as it does not take string literals into account. For example:
<langsyntaxhighlight Haskelllang="haskell">test = "This {- is not the beginning of a block comment" -- Do your homework properly -}</langsyntaxhighlight>
Comment delimiters can be changed by calling stripComments with different start and end parameters.
<langsyntaxhighlight Haskelllang="haskell">import Data.List
 
stripComments :: String -> String -> String -> String
Line 869 ⟶ 1,327:
| otherwise = inComment $ tail xs
 
main = interact (stripComments "/*" "*/")</langsyntaxhighlight>
Output:
<pre>
Line 885 ⟶ 1,343:
=={{header|Icon}} and {{header|Unicon}}==
If one is willing to concede that the program file will fit in memory, then the following code works:
<langsyntaxhighlight Iconlang="icon">procedure main()
every (unstripped := "") ||:= !&input || "\n" # Load file as one string
write(stripBlockComment(unstripped,"/*","*/"))
Line 900 ⟶ 1,358:
return result || tab(0)
}
end</langsyntaxhighlight>
Otherwise, the following handles an arbitrary length input:
<langsyntaxhighlight Iconlang="icon">procedure main()
every writes(stripBlockComment(!&input,"/*","*/"))
end
Line 915 ⟶ 1,373:
else fail
}
end</langsyntaxhighlight>
 
=={{header|J}}==
<langsyntaxhighlight lang="j">strip=:#~1 0 _1*./@:(|."0 1)2>4{"1(5;(0,"0~".;._2]0 :0);'/*'i.a.)&;:
1 0 0
0 2 0
2 3 2
0 2 2
)</langsyntaxhighlight>
Example data:
<langsyntaxhighlight lang="j">example=: 0 :0
/**
* Some comments
Line 942 ⟶ 1,400:
function something() {
}
)</langsyntaxhighlight>
Example use:
<langsyntaxhighlight lang="j"> strip example
function subroutine() {
Line 953 ⟶ 1,411:
function something() {
}</langsyntaxhighlight>
Here is a version which allows the delimiters to be passed as an optional left argument as a pair of strings:
<langsyntaxhighlight lang="j">stripp=:3 :0
('/*';'*/') stripp y
:
Line 961 ⟶ 1,419:
marks=. (+./(-i._1+#open,close)|."0 1 open E. y) - close E.&.|. y
y #~ -. (+._1&|.) (1 <. 0 >. +)/\.&.|. marks
)</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">import java.io.*;
 
public class StripBlockComments{
Line 1,013 ⟶ 1,471:
}
}
}</langsyntaxhighlight>
 
=={{header|jq}}==
Line 1,019 ⟶ 1,477:
 
The filter <tt>strip_block_comments/2</tt> as defined here does not attempt to recognize comments-within-comments.
<langsyntaxhighlight lang="jq">def strip_block_comments(open; close):
def deregex:
reduce ("\\\\", "\\*", "\\^", "\\?", "\\+", "\\.",
Line 1,027 ⟶ 1,485:
gsub( (open|deregex) + ".*?" + (close|deregex); ""; "m") ;
 
strip_block_comments("/*"; "*/")</langsyntaxhighlight>
'''Invocation''':
$ jq -s -R -r -f Strip_block_comments.jq sample_text_for_stripping.txt
Line 1,034 ⟶ 1,492:
{{works with|Julia|0.6}}
{{trans|Python}}
<langsyntaxhighlight lang="julia">function _stripcomments(txt::AbstractString, dlm::Tuple{String,String})
"Strips first nest of block comments"
 
Line 1,108 ⟶ 1,566:
end
 
main()</langsyntaxhighlight>
 
{{out}}
Line 1,132 ⟶ 1,590:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.4-3
 
val sample = """
Line 1,182 ⟶ 1,640:
println(stripBlockComments(sample))
println(stripBlockComments(sample2, "``{", "``}"))
}</langsyntaxhighlight>
 
{{out}}
Line 1,207 ⟶ 1,665:
}
 
</pre>
 
=={{header|Ksh}}==
<syntaxhighlight lang="ksh">
#!/bin/ksh
 
# Strip block comments
 
# # Variables:
#
bd=${1:-'/*'}
ed=${2:-'*/'}
 
testcase='/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
/**
* Another comment.
*/
function something() {
}'
 
######
# main #
######
 
testcase=${testcase%%"${bd}"*}
while [[ -n ${.sh.match} ]]; do # .sh.match stores the most recent match
if [[ -n ${testcase} ]]; then
sm="${.sh.match}"
sm="${sm/"${bd}"/}"
buff="${testcase}"
buff+="${sm#*"${ed}"}"
testcase="${buff}"
else
testcase="${.sh.match}"
testcase="${testcase#*"${ed}"}"
fi
testcase=${testcase%%"${bd}"*}
done
 
echo "${testcase}"
</syntaxhighlight>
{{out}}<pre>
 
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}
</pre>
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">global CRLF$
CRLF$ =chr$( 13) +chr$( 10)
 
Line 1,254 ⟶ 1,773:
end if
next i
end function</langsyntaxhighlight>
<pre>
 
Line 1,277 ⟶ 1,796:
=={{header|Lua}}==
It is assumed, that the code is in the file "Text1.txt".
<langsyntaxhighlight lang="lua">filename = "Text1.txt"
 
fp = io.open( filename, "r" )
Line 1,284 ⟶ 1,803:
 
stripped = string.gsub( str, "/%*.-%*/", "" )
print( stripped )</langsyntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">StringReplace[a,"/*"~~Shortest[___]~~"*/" -> ""]
 
->
Line 1,297 ⟶ 1,816:
function something() {
}</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight Matlablang="matlab">function str = stripblockcomment(str,startmarker,endmarker)
while(1)
ix1 = strfind(str, startmarker);
Line 1,312 ⟶ 1,831:
end;
end;
end;</langsyntaxhighlight>
Output:
<pre>
Line 1,351 ⟶ 1,870:
=={{header|Nim}}==
{{trans|Python}}
<langsyntaxhighlight lang="nim">import strutils
 
proc commentStripper(txt: string; delim: tuple[l, r: string] = ("/*", "*/")): string =
let i = txt.find(delim.l)
if i < 0: return txt
return txt
 
result = if i > 0: txt[0 .. < i] else: ""
let tmp = commentStripper(txt[i+delim.l.len .. txt.high], delim)
let j = tmp.find(delim.r)
assert j >= 0
Line 1,398 ⟶ 1,916:
*/
function something() {
}""")</langsyntaxhighlight>
 
Output:
{{out}}
<pre>NON-NESTED BLOCK COMMENT EXAMPLE:
 
Line 1,418 ⟶ 1,937:
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl -w
use strict ;
use warnings ;
Line 1,430 ⟶ 1,949:
close FH ;
$code =~ s,/\*.*?\*/,,sg ;
print $code . "\n" ;</langsyntaxhighlight>
Output:
<pre>
Line 1,443 ⟶ 1,962:
</pre>
 
=={{header|Perl 6Phix}}==
Note that Phix itself supports nested block comments, which this simple approach will not handle properly - see ptok.e/SkipBlockComment() and/or pwa/src/p2js_tok.e/block_comment(), which both use a slightly more convoluted and recursive but also more precise character-by-character method.
<lang perl6>sample().split(/ '/*' .+? '*/' /).print;
<!--<syntaxhighlight lang="phix">(phixonline)-->
 
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sub sample {
<span style="color: #008080;">constant</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
' /**
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <&lt;-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
'} """</langspan>
Output:
<span style="color: #008080;">function</span> <span style="color: #000000;">strip_comments</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">text</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">startc</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"/*"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">endc</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"*/"</span><span style="color: #0000FF;">)</span>
<pre>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
function subroutine() {
<span style="color: #004080;">integer</span> <span style="color: #000000;">startp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #000000;">startc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">endp</span>
a = b + c ;
<span style="color: #008080;">if</span> <span style="color: #000000;">startp</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
}
<span style="color: #000000;">endp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #000000;">endc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">startp</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">startc</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">endp</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"error"</span><span style="color: #0000FF;">)</span>
 
<span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">startp</span><span style="color: #0000FF;">..</span><span style="color: #000000;">endp</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">endc</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
function something() {
<span style="color: #008080;">return</span> <span style="color: #000000;">text</span>
}
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
</pre>
 
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strip_comments</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">))</span>
=={{header|Phix}}==
<!--</syntaxhighlight>-->
<lang Phix>constant test = """
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
"""
 
function strip_comments(string text, startc="/*", endc="*/")
while 1 do
integer startp = match(startc,text)
if startp=0 then exit end if
integer endp = match(endc,text,startp+length(startc))
if endp=0 then
puts(1,"error, aborting...")
abort(0)
end if
text[startp..endp+length(endc)-1] = ""
end while
return text
end function
 
puts(1,strip_comments(test))</lang>
{{out}}
<pre>
Line 1,525 ⟶ 2,012:
 
=={{header|PHP}}==
<syntaxhighlight lang="php">
<lang PHP>
function strip_block_comments( $test_string ) {
$pattern = "/^.*?(\K\/\*.*?\*\/)|^.*?(\K\/\*.*?^.*\*\/)$/mXsusmXus";
return preg_replace( $pattern, '', $test_string );
}
Line 1,549 ⟶ 2,036:
}
" ) . "'";
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,567 ⟶ 2,054:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(in "sample.txt"
(while (echo "/*")
(out "/dev/null" (echo "*/")) ) )</langsyntaxhighlight>
Output:
<pre>
Line 1,583 ⟶ 2,070:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">/* A program to remove comments from text. */
strip: procedure options (main); /* 8/1/2011 */
declare text character (80) varying;
Line 1,616 ⟶ 2,103:
end;
 
end strip;</langsyntaxhighlight>
 
=={{header|Prolog}}==
 
Prolog enables grammar rules via the DCG that are ideally suited for this task .
 
<syntaxhighlight lang="prolog">
 
:- system:set_prolog_flag(double_quotes,codes) .
 
strip_block_comments(INPUTz)
:-
strip_block_comments(INPUTz,OUTPUTz) ,
system:format("```~n",[OUTPUTz]) ,
system:format("~s~n",[OUTPUTz]) ,
system:format("```~n",[OUTPUTz])
.
 
strip_block_comments(INPUTz,OUTPUTz)
:-
prolog:phrase(block(OUTPUTz),INPUTz)
.
 
block([]) --> \+ [_] , ! .
block([CODE|OUTPUTz]) --> \+ comment , ! , [CODE] , block(OUTPUTz) .
block(OUTPUTz) --> comment , ! , block(OUTPUTz) .
 
comment --> comment_entr , zero_or_more(comment_each) , comment_exit .
comment_entr --> "/*" .
comment_each --> comment , ! .
comment_each --> \+ comment_exit , ! , [_] .
comment_exit --> "*/" .
 
zero_or_more(CALLABLE) --> call(CALLABLE) , ! , zero_or_more(CALLABLE) .
zero_or_more(_) --> ! .
 
</syntaxhighlight>
 
{{out}}
<pre>
/*
?- strip_block_comments(
"
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
").
```
 
 
function subroutine() {
a = b + c ;
}
 
function something() {
}
 
```
true .
 
?-
*/
 
/*
?- strip_block_comments("abc/*p/*q*/r*/def") .
```
abcdef
```
true .
 
?- strip_block_comments("abcdef") .
```
abcdef
```
true .
 
</pre>
 
=={{header|PureBasic}}==
Solution using regular expressions. A procedure to stripBlocks() procedure is defined that will strip comments between any two delimeters.
<langsyntaxhighlight PureBasiclang="purebasic">Procedure.s escapeChars(text.s)
Static specialChars.s = "[\^$.|?*+()"
Protected output.s, nextChar.s, i, countChar = Len(text)
Line 1,670 ⟶ 2,248:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Sample output:
<pre>--- source ---
Line 1,714 ⟶ 2,292:
=={{header|Python}}==
The code has comment delimeters as an argument and will also strip ''nested'' block comments.
<langsyntaxhighlight lang="python">def _commentstripper(txt, delim):
'Strips first nest of block comments'
Line 1,737 ⟶ 2,315:
while deliml in txt:
txt = _commentstripper(txt, delim)
return txt</langsyntaxhighlight>
;Tests and sample output
<langsyntaxhighlight lang="python">def test():
print('\nNON-NESTED BLOCK COMMENT EXAMPLE:')
sample = ''' /**
Line 1,779 ⟶ 2,357:
if __name__ == '__main__':
test()</langsyntaxhighlight>
 
<pre>
Line 1,801 ⟶ 2,379:
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang at-exp racket
 
Line 1,830 ⟶ 2,408:
}
})
</syntaxhighlight>
</lang>
 
(Outputs the expected text...)
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sample().split(/ '/*' .+? '*/' /).print;
 
sub sample {
' /**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
'}</syntaxhighlight>
Output:
<pre>
function subroutine() {
a = b + c ;
}
 
function something() {
}
</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/* REXX ***************************************************************
* Split comments
* This program ignores comment delimiters within literal strings
Line 1,933 ⟶ 2,545:
 
oc: Return lineout(oic,oc)
op: Return lineout(oip,op)</langsyntaxhighlight>
Input:
<pre>
Line 1,995 ⟶ 2,607:
</pre>
 
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
example = "123/*456*/abc/*def*/789"
Line 2,012 ⟶ 2,623:
end
see example2 + nl
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def remove_comments!(str, comment_start='/*', comment_end='*/')
while start_idx = str.index(comment_start)
end_idx = str.index(comment_end, start_idx + comment_start.length) + comment_end.length - 1
Line 2,046 ⟶ 2,657:
END_OF_STRING
 
puts remove_comments example</langsyntaxhighlight>
outputs
<pre>
Line 2,057 ⟶ 2,668:
function something() {
}</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">import java.util.regex.Pattern.quote
def strip1(x: String, s: String = "/*", e: String = "*/") =
x.replaceAll("(?s)"+quote(s)+".*?"+quote(e), "")</langsyntaxhighlight>
<langsyntaxhighlight Scalalang="scala">def strip2(x: String, s: String = "/*", e: String = "*/"): String = {
val a = x indexOf s
val b = x indexOf (e, a + s.length)
if (a == -1 || b == -1) x
else strip2(x.take(a) + x.drop(b + e.length), s, e)
}</langsyntaxhighlight>
<langsyntaxhighlight Scalalang="scala">def strip3(x: String, s: String = "/*", e: String = "*/"): String = x.indexOf(s) match {
case -1 => x
case i => x.indexOf(e, i + s.length) match {
Line 2,073 ⟶ 2,685:
case j => strip2(x.take(i) + x.drop(j + e.length), s, e)
}
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
Line 2,079 ⟶ 2,691:
can be used to replace unnested comments.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const proc: main is func
Line 2,102 ⟶ 2,714:
begin
writeln(replace2(stri, "/*", "*/", " "));
end func;</langsyntaxhighlight>
Output:
<pre>
Line 2,118 ⟶ 2,730:
=={{header|Sidef}}==
For extra credit, it allows the caller to redefine the delimiters.
<langsyntaxhighlight lang="ruby">func strip_block_comments(code, beg='/*', end='*/') {
var re = Regex.new(beg.escape + '.*?' + end.escape, 's');
code.gsub(re, '');
}
 
say strip_block_comments(ARGF.slurp);</langsyntaxhighlight>
 
=={{header|SNOBOL4}}==
{{works with|SNOBOL4, SPITBOL for Linux}}
<syntaxhighlight lang="snobol4">
* Program: strip_block_comments.sbl
* To run: sbl -r extract_extension.sbl
* Description: Strip block comments.
* Can use different begin and end delimiters.
* Handles comment nesting and unmatched end delimiters.
* Unmatched begin delimiters remove text to end of file.
* Does not handle quoted delimiters.
* Most null lines are removed, which may not be
* what is desired.
* Comment: Tested using the Spitbol for Linux version of SNOBOL4
 
 
* Function strip_block_comments will read a file, or the text after
* the END statement below. Parameter bcom is the beginning comment
* string and parameter ecom is the ending comment string.
*
define('strip_block_comments(bcom,ecom)break_chars,c,newc,pre,pc,b')
pat1 = breakx(*break_chars) . pre (*bcom | *gt(b,0) *ecom) . pc
:(strip_block_comments_end)
strip_block_comments
break_chars = substr(bcom,1,1) substr(ecom,1,1)
newc = ""
b = 0
in1
c = input :f(p60)
 
p10
c ? pat1 = "" :f(p20)
 
* matches
le(b,0) :s(leb)f(gtb)
leb
b = leq(pc,bcom) b + 1 :f(leb2)
newc = newc pre :(p10)
leb2
b = leq(pc,ecom) b - 1 :f(error)
:(p10)
gtb
b = leq(pc,bcom) b + 1
b = leq(pc,ecom) b - 1
:(p10)
 
* nomatches
p20
newc = lt(b,1) newc c
ident(newc) :s(in1)
:(p50)
 
p50
output = newc
newc = "" :(in1)
 
p60
output = differ(newc) newc
:(return)
strip_block_comments_end
 
 
* Set "begin" comment delimiter (bcom) and "end" comment delimiter (ecom) below
bcom = "/*"
ecom = "*/"
* bcom = "{{*"
* ecom = "?/"
 
* Strip block comments from the text lines after the END statement
strip_block_comments(bcom,ecom)
 
END
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
 
----------------------------------------------
With nested comments/* Nested /* comment*/s*/*/!
Unmatched"/*" end delimiters simply remove
to end of file
</syntaxhighlight>
{{out}}
<pre>
function subroutine() {
a = b + c ;
}
function something() {
}
----------------------------------------------
With nested comments*/!
Unmatched"
</pre>
 
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
func stripBlocks(from str: String, open: String = "/*", close: String = "*/") -> String {
guard !open.isEmpty && !close.isEmpty else {
return str
}
 
var ret = str
 
while let begin = ret.range(of: open), let end = ret[begin.upperBound...].range(of: close) {
ret.replaceSubrange(Range(uncheckedBounds: (begin.lowerBound, end.upperBound)), with: "")
}
 
return ret
}
 
let test = """
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}
"""
 
print(stripBlocks(from: test))</syntaxhighlight>
 
{{out}}
 
<pre>
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}
 
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc stripBlockComment {string {openDelimiter "/*"} {closeDelimiter "*/"}} {
# Convert the delimiters to REs by backslashing all non-alnum characters
set openAsRE [regsub -all {\W} $openDelimiter {\\&}]
Line 2,133 ⟶ 2,905:
# Now remove the blocks using a dynamic non-greedy regular expression
regsub -all "$openAsRE.*?$closeAsRE" $string ""
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl">puts [stripBlockComment " /**
* Some comments
* longer comments here that we can parse.
Line 2,151 ⟶ 2,923:
function something() {
}
"]</langsyntaxhighlight>
Output:
<pre>
Line 2,165 ⟶ 2,937:
 
</pre>
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang="tuscript">
$$ MODE DATA
$$ script=*
Line 2,204 ⟶ 2,977:
d=FILE("destfile")
TRACE *d
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,214 ⟶ 2,987:
4 =
5 = function something() { }
</pre>
 
=={{header|VBA}}==
Stripping block comments might look easy ...
<syntaxhighlight lang="vb">'strip block comment NESTED comments
'multi line comments
'and what if there are string literals with these delimeters?
'------------------------
'delimeters for Block Comment can be specified, exactly two characters each
'Three states: Block_Comment, String_Literal, Other_Text
'Globals:
Dim t As String 'target string
Dim s() As Byte 'source array
Dim j As Integer 'index into the source string s, converted to byte array
Dim SourceLength As Integer 'of a base 0 array, so last byte is SourceLength - 1
Dim flag As Boolean
Private Sub Block_Comment(sOpBC As String, sClBC As String)
'inside a block comment, expecting close block comment delimeter
flag = False
Do While j < SourceLength - 2
Select Case s(j)
Case Asc(Left(sOpBC, 1))
If s(j + 1) = Asc(Right(sOpBC, 1)) Then
'open block NESTED comment delimeter found
j = j + 2
Block_Comment sOpBC, sClBC
End If
Case Asc(Left(sClBC, 1))
If s(j + 1) = Asc(Right(sClBC, 1)) Then
'close block comment delimeter found
flag = True
j = j + 2
Exit Do
End If
'just a lone star
Case Else
End Select
j = j + 1
Loop
If Not flag Then MsgBox "Error, missing close block comment delimeter"
End Sub
Private Sub String_Literal()
'inside as string literal, expecting double quote as delimeter
flag = False
Do While j < SourceLength - 2
If s(j) = Asc("""") Then
If s(j + 1) = Asc("""") Then
'found a double quote within a string literal
t = t + Chr(s(j))
j = j + 1
Else
'close string literal delimeter found
flag = True
t = t + Chr(s(j))
j = j + 1
Exit Do
End If
End If
t = t + Chr(s(j))
j = j + 1
Loop
If Not flag Then MsgBox "Error, missing closing string delimeter"
End Sub
Private Sub Other_Text(Optional sOpBC As String = "/*", Optional sClBC As String = "*/")
If Len(sOpBC) <> 2 Then
MsgBox "Error, open block comment delimeter must be 2" & _
" characters long, got " & Len(sOpBC) & " characters"
Exit Sub
End If
If Len(sClBC) <> 2 Then
MsgBox "Error, close block comment delimeter must be 2" & _
" characters long, got " & Len(sClBC) & " characters"
Exit Sub
End If
Do While j < SourceLength - 1
Select Case s(j)
Case Asc(""""):
t = t + Chr(s(j))
j = j + 1
String_Literal
Case Asc(Left(sOpBC, 1))
If s(j + 1) = Asc(Right(sOpBC, 1)) Then
'open block comment delimeter found
j = j + 2
Block_Comment sOpBC, sClBC
Else
t = t + Chr(s(j))
j = j + 1
End If
Case Else
t = t + Chr(s(j))
j = j + 1
End Select
Loop
If j = SourceLength - 1 Then t = t + Chr(s(j))
End Sub
Public Sub strip_block_comment()
Dim n As String
n = n & "/**" & vbCrLf
n = n & "* Some comments /*NESTED COMMENT*/" & vbCrLf
n = n & "* longer comments here that we can parse." & vbCrLf
n = n & "*" & vbCrLf
n = n & "* Rahoo" & vbCrLf
n = n & "*/" & vbCrLf
n = n & "mystring = ""This is the """"/*"""" open comment block mark.""" & vbCrLf
'VBA converts two double quotes in a row within a string literal to a single double quote
'see the output below. Quadruple double quotes become two double quotes within the string
'to represent a single double quote within a string.
n = n & "function subroutine() {" & vbCrLf
n = n & "a = /* inline comment */ b + c ;" & vbCrLf
n = n & "}" & vbCrLf
n = n & "/*/ <-- tricky /*NESTED*/ comments */" & vbCrLf
n = n & "" & vbCrLf
n = n & "/**" & vbCrLf
n = n & "* Another comment." & vbCrLf
n = n & "*/" & vbCrLf
n = n & "function something() {" & vbCrLf
n = n & "}"
s = StrConv(n, vbFromUnicode)
j = 0
t = ""
SourceLength = Len(n)
Other_Text 'The open and close delimeters for block comment are optional ;)
Debug.Print "Original text:"
Debug.Print String$(60, "-")
Debug.Print n & vbCrLf
Debug.Print "Text after deleting comment blocks, preserving string literals:"
Debug.Print String$(60, "-")
Debug.Print t
End Sub</syntaxhighlight>{{out}}<pre>Original text:
------------------------------------------------------------
/**
* Some comments /*NESTED COMMENT*/
* longer comments here that we can parse.
*
* Rahoo
*/
mystring = "This is the ""/*"" open comment block mark."
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky /*NESTED*/ comments */
 
/**
* Another comment.
*/
function something() {
}
 
Text after deleting comment blocks, preserving string literals:
------------------------------------------------------------
 
mystring = "This is the ""/*"" open comment block mark."
function subroutine() {
a = b + c ;
}
 
 
 
function something() {
}</pre>
 
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang="wren">var stripper = Fn.new { |start, end|
if (start == "" || end == "") {
start = "/*"
end = "*/"
}
return Fn.new { |source|
while (true) {
var cs = source.indexOf(start)
if (cs == -1) break
var ce = source[cs+2..-1].indexOf(end)
if (ce == -1) break
source = source[0...cs] + source[cs+ce+4..-1]
}
return source
}
}
 
var source = "/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* Another comment.
*/
function something() {
}"
 
var stripC = stripper.call("", "")
System.print(stripC.call(source))</syntaxhighlight>
 
{{out}}
<pre>
 
function subroutine() {
a = b + c ;
}
 
function something() {
}
</pre>
 
=={{header|XProfan}}==
<syntaxhighlight lang="xprofan">Proc strip_block_comments
Parameters string inhalt, beg_delim, end_delim
Declare long start, ende, anzahl
start = 1
start = InStr(beg_delim, inhalt, start)
While start > 0
ende = InStr(end_delim, inhalt, start + len(beg_delim))
If ende > 0
anzahl = ende + + len(end_delim) - start
inhalt = Del$(inhalt, start, anzahl)
Else
BREAK
EndIf
start = InStr(beg_delim, inhalt, start)
EndWhile
Return inhalt
EndProc
 
Cls
Declare string Text
Text = BlockRead("C:\Temp\Multiline_comment.txt")
Text = strip_block_comments(Text, "/*", "*/")
Print "Output:"
Print Text
WaitKey
End</syntaxhighlight>
{{out}}
<pre>
function subroutine() {
a = b + c ;
}
 
function something() {
}
 
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn stripper(text, a="/*", b="*/"){
while(xy:=text.span(a,b,True)){ x,y:=xy; text=text[0,x] + text[x+y,*] }
text
}</langsyntaxhighlight>
The span method takes two tokens and matches the shortest or longest balanced match (if True). It assumes there are no escape characters (such as \ or ""). So we just repeatedly strip out the longest balanced comments until there aren't any left (span returns the empty list). If a comment was unbalanced, span would fail but this code doesn't check that and just assumes no more matches.
{{out}}
9,482

edits