Strip block comments: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (pluralized a word.)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(12 intermediate revisions by 12 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 37 ⟶ 38:
;Extra credit:
Ensure that the stripping code is not hard-coded to the particular delimiters described above, but instead allows the caller to specify them.   (If your language supports them,   [[Optional parameters|optional parameters]]   may be useful for this.)
 
 
{{Template:Strings}}
<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 135 ⟶ 186:
end loop;
Ada.Text_IO.Close (File => File);
end Strip;</langsyntaxhighlight>
output:
<pre>
Line 156 ⟶ 207:
=={{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.
<langsyntaxhighlight lang="algolw">begin
% strips block comments from a source %
% the source is read from standard input and the result written to %
Line 274 ⟶ 325:
% text stripBlockComments for C-style source %
stripBlockComments( "/*", "*/", """", "'", "\" )
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 296 ⟶ 347:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">code =
(
/**
Line 322 ⟶ 373:
closeC:=RegExReplace(closeC,"(\*|\^|\?|\\|\+|\.|\!|\{|\}|\[|\]|\$|\|)","\$0")
;Display final result
MsgBox % sCode := RegExReplace(code,"s)(" . openC . ").*?(" . closeC . ")")</langsyntaxhighlight>
<pre>
 
Line 333 ⟶ 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 373 ⟶ 461:
CLOSE #infile%
CLOSE #outfile%
ENDPROC</langsyntaxhighlight>
Output file:
<pre>
Line 388 ⟶ 476:
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
Line 440 ⟶ 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 458 ⟶ 546:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight Csharplang="csharp">using System;
 
class Program
Line 475 ⟶ 563:
return sampleText;
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <string>
#include <iostream>
#include <iterator>
Line 501 ⟶ 589:
return 1 ;
}
}</langsyntaxhighlight>
Output:
<pre>
Line 517 ⟶ 605:
 
=={{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 528 ⟶ 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 573 ⟶ 661:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.algorithm, std.regex;
 
string[2] separateComments(in string txt,
Line 661 ⟶ 749:
 
showResults(ex2, separateComments(ex2, `#|;`, `[\n\r]|$`));
}</langsyntaxhighlight>
{{out}}
<pre>===Original text:
Line 717 ⟶ 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.
<langsyntaxhighlight lang="fsharp">open System
open System.Text.RegularExpressions
 
Line 763 ⟶ 942:
let balancedC = balancedComments "/*" "*/"
printfn "%s" (balancedC.Replace(sample, ""))
0</langsyntaxhighlight>
Output
<pre>
Line 779 ⟶ 958:
=={{header|Factor}}==
===Regexp implementation===
<langsyntaxhighlight lang="factor">
: strip-block-comments ( string -- string )
R/ /\*.*?\*\// "" re-replace ;
</syntaxhighlight>
</lang>
===Manual implementation===
<langsyntaxhighlight lang="factor">
USING: kernel io accessors strings math sequences locals
io.streams.string multiline prettyprint ;
Line 869 ⟶ 1,048:
 
MAIN: test-strip-block-comments
</syntaxhighlight>
</lang>
 
=={{header|Fortran}}==
Line 884 ⟶ 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 968 ⟶ 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 1,002 ⟶ 1,181:
 
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|FreeBASIC}}==
{{trans|Liberty BASIC}}
<syntaxhighlight lang="freebasic">Const CRLF = Chr(13) + Chr(10)
 
Function stripBlocks(text As String, first As String, last As String) As String
Dim As String temp = ""
For i As Integer = 1 To Len(text) - Len(first)
If Mid(text, i, Len(first)) = first Then
i += Len(first)
Do
If Mid(text, i, 2) = CRLF Then temp &= CRLF
i += 1
Loop Until (Mid(text, i, Len(last)) = last) Or (i = Len(text) - Len(last))
i += Len(last) -1
Else
temp &= Mid(text, i, 1)
End If
Next i
Return temp
End Function
 
Dim As String source
source = " /**" + CRLF + _
" * Some comments" + CRLF + _
" * longer comments here that we can parse." + CRLF + _
" *" + CRLF + _
" * Rahoo " + CRLF + _
" */" + CRLF + _
" function subroutine() {" + CRLF + _
" a = /* inline comment */ b + c ;" + CRLF + _
" }" + CRLF + _
" /*/ <-- tricky comments */" + CRLF + _
"" + CRLF + _
" /**" + CRLF + _
" * Another comment." + CRLF + _
" */" + CRLF + _
" function something() {" + CRLF + _
" }" + CRLF
 
Print stripBlocks(source, "/*", "*/")
Sleep</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de Liberty BASIC.
</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 1,058 ⟶ 1,284:
function something() {
}`))
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">def code = """
/**
* Some comments
Line 1,080 ⟶ 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 1,101 ⟶ 1,327:
| otherwise = inComment $ tail xs
 
main = interact (stripComments "/*" "*/")</langsyntaxhighlight>
Output:
<pre>
Line 1,117 ⟶ 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 1,132 ⟶ 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 1,147 ⟶ 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 1,174 ⟶ 1,400:
function something() {
}
)</langsyntaxhighlight>
Example use:
<langsyntaxhighlight lang="j"> strip example
function subroutine() {
Line 1,185 ⟶ 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 1,193 ⟶ 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,245 ⟶ 1,471:
}
}
}</langsyntaxhighlight>
 
=={{header|jq}}==
Line 1,251 ⟶ 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,259 ⟶ 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,266 ⟶ 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,340 ⟶ 1,566:
end
 
main()</langsyntaxhighlight>
 
{{out}}
Line 1,364 ⟶ 1,590:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.4-3
 
val sample = """
Line 1,414 ⟶ 1,640:
println(stripBlockComments(sample))
println(stripBlockComments(sample2, "``{", "``}"))
}</langsyntaxhighlight>
 
{{out}}
Line 1,439 ⟶ 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,486 ⟶ 1,773:
end if
next i
end function</langsyntaxhighlight>
<pre>
 
Line 1,509 ⟶ 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,516 ⟶ 1,803:
 
stripped = string.gsub( str, "/%*.-%*/", "" )
print( stripped )</langsyntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">StringReplace[a,"/*"~~Shortest[___]~~"*/" -> ""]
 
->
Line 1,529 ⟶ 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,544 ⟶ 1,831:
end;
end;
end;</langsyntaxhighlight>
Output:
<pre>
Line 1,583 ⟶ 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: ""
Line 1,630 ⟶ 1,916:
*/
function something() {
}""")</langsyntaxhighlight>
 
Output:
{{out}}
<pre>NON-NESTED BLOCK COMMENT EXAMPLE:
 
Line 1,650 ⟶ 1,937:
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl -w
use strict ;
use warnings ;
Line 1,662 ⟶ 1,949:
close FH ;
$code =~ s,/\*.*?\*/,,sg ;
print $code . "\n" ;</langsyntaxhighlight>
Output:
<pre>
Line 1,676 ⟶ 1,963:
 
=={{header|Phix}}==
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 Phix>constant test = """
<!--<syntaxhighlight lang="phix">(phixonline)-->
/**
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
* Some comments
<span style="color: #008080;">constant</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
 
/**
* AnotherSome comment.comments
* longer comments here that we can parse.
*
* Rahoo
*/
function somethingsubroutine() {
a = /* inline comment */ b + c ;
}
/*/ &lt;-- tricky comments */
"""
 
/**
function strip_comments(string text, startc="/*", endc="*/")
while 1* doAnother comment.
*/
integer startp = match(startc,text)
function something() {
if startp=0 then exit end if
}
integer endp = match(endc,text,startp+length(startc))
"""</span>
if endp=0 then
puts(1,"error, aborting...")
<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>
abort(0)
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
end if
<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>
text[startp..endp+length(endc)-1] = ""
<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>
end while
<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>
return text
<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>
end function
<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>
puts(1,strip_comments(test))</lang>
<span style="color: #008080;">return</span> <span style="color: #000000;">text</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,724 ⟶ 2,012:
 
=={{header|PHP}}==
<syntaxhighlight lang="php">
<lang PHP>
function strip_block_comments( $test_string ) {
$pattern = "/^.*?(\K\/\*.*?\*\/)|^.*?(\K\/\*.*?^.*\*\/)$/mXus";
Line 1,748 ⟶ 2,036:
}
" ) . "'";
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,766 ⟶ 2,054:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(in "sample.txt"
(while (echo "/*")
(out "/dev/null" (echo "*/")) ) )</langsyntaxhighlight>
Output:
<pre>
Line 1,782 ⟶ 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,815 ⟶ 2,103:
end;
 
end strip;</langsyntaxhighlight>
 
=={{header|Prolog}}==
Line 1,821 ⟶ 2,109:
Prolog enables grammar rules via the DCG that are ideally suited for this task .
 
<langsyntaxhighlight lang="prolog">
 
:- system:set_prolog_flag(double_quotes,codes) .
Line 1,851 ⟶ 2,139:
zero_or_more(_) --> ! .
 
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,910 ⟶ 2,198:
=={{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,960 ⟶ 2,248:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Sample output:
<pre>--- source ---
Line 2,004 ⟶ 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 2,027 ⟶ 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 2,069 ⟶ 2,357:
if __name__ == '__main__':
test()</langsyntaxhighlight>
 
<pre>
Line 2,091 ⟶ 2,379:
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang at-exp racket
 
Line 2,120 ⟶ 2,408:
}
})
</syntaxhighlight>
</lang>
 
(Outputs the expected text...)
Line 2,126 ⟶ 2,414:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>sample().split(/ '/*' .+? '*/' /).print;
 
sub sample {
Line 2,145 ⟶ 2,433:
function something() {
}
'}</langsyntaxhighlight>
Output:
<pre>
Line 2,159 ⟶ 2,447:
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/* REXX ***************************************************************
* Split comments
* This program ignores comment delimiters within literal strings
Line 2,257 ⟶ 2,545:
 
oc: Return lineout(oic,oc)
op: Return lineout(oip,op)</langsyntaxhighlight>
Input:
<pre>
Line 2,321 ⟶ 2,609:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
example = "123/*456*/abc/*def*/789"
Line 2,335 ⟶ 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,369 ⟶ 2,657:
END_OF_STRING
 
puts remove_comments example</langsyntaxhighlight>
outputs
<pre>
Line 2,382 ⟶ 2,670:
 
=={{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,397 ⟶ 2,685:
case j => strip2(x.take(i) + x.drop(j + e.length), s, e)
}
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
Line 2,403 ⟶ 2,691:
can be used to replace unnested comments.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const proc: main is func
Line 2,426 ⟶ 2,714:
begin
writeln(replace2(stri, "/*", "*/", " "));
end func;</langsyntaxhighlight>
Output:
<pre>
Line 2,442 ⟶ 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}}==
 
<langsyntaxhighlight lang="swift">import Foundation
 
func stripBlocks(from str: String, open: String = "/*", close: String = "*/") -> String {
Line 2,486 ⟶ 2,881:
"""
 
print(stripBlocks(from: test))</langsyntaxhighlight>
 
{{out}}
Line 2,503 ⟶ 2,898:
 
=={{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,510 ⟶ 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,528 ⟶ 2,923:
function something() {
}
"]</langsyntaxhighlight>
Output:
<pre>
Line 2,544 ⟶ 2,939:
 
=={{header|TUSCRIPT}}==
<langsyntaxhighlight lang="tuscript">
$$ MODE DATA
$$ script=*
Line 2,582 ⟶ 2,977:
d=FILE("destfile")
TRACE *d
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,596 ⟶ 2,991:
=={{header|VBA}}==
Stripping block comments might look easy ...
<langsyntaxhighlight lang="vb">'strip block comment NESTED comments
'multi line comments
'and what if there are string literals with these delimeters?
Line 2,721 ⟶ 3,116:
Debug.Print String$(60, "-")
Debug.Print t
End Sub</langsyntaxhighlight>{{out}}<pre>Original text:
------------------------------------------------------------
/**
Line 2,756 ⟶ 3,151:
=={{header|Wren}}==
{{trans|Go}}
<langsyntaxhighlight ecmascriptlang="wren">var stripper = Fn.new { |start, end|
if (start == "" || end == "") {
start = "/*"
Line 2,791 ⟶ 3,186:
 
var stripC = stripper.call("", "")
System.print(stripC.call(source))</langsyntaxhighlight>
 
{{out}}
Line 2,807 ⟶ 3,202:
 
=={{header|XProfan}}==
<langsyntaxhighlight XProfanlang="xprofan">Proc strip_block_comments
Parameters string inhalt, beg_delim, end_delim
Declare long start, ende, anzahl
Line 2,832 ⟶ 3,227:
Print Text
WaitKey
End</langsyntaxhighlight>
{{out}}
<pre>
Line 2,848 ⟶ 3,243:
 
=={{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,476

edits