proc NumOut(Num);       \Output positive integer with commas
int  Num, Dig, Cnt;
[Cnt:= [0];
Num:= Num/10;
Dig:= rem(0);
Cnt(0):= Cnt(0)+1;
if Num then NumOut(Num);
Cnt(0):= Cnt(0)-1;
ChOut(0, Dig+^0);
if rem(Cnt(0)/3)=0 & Cnt(0) then ChOut(0, ^,);
];

func IsPrime(N);        \Return 'true' if odd N > 2 is prime
int  N, I;
[for I:= 3 to sqrt(N) do
    [if rem(N/I) = 0 then return false;
    I:= I+1;
    ];
return true;
];

int StrongCnt, WeakCnt, StrongCnt0, WeakCnt0, Strongs(36), Weaks(37);
int N, P0, P1, P2, T;
[StrongCnt:= 0;  WeakCnt:= 1;
Weaks(0):= 3;
N:= 7;  P1:= 3;  P2:= 5;        \handles unique case where (2+5)/2 = 3.5
repeat  if IsPrime(N) then
            [P0:= P1;  P1:= P2;  P2:= N;
            T:= (P0+P2)/2;
            if P1 > T then
                [if StrongCnt < 36 then Strongs(StrongCnt):= P1;
                StrongCnt:= StrongCnt+1;
                ];
            if P1 < T then
                [if WeakCnt < 37 then Weaks(WeakCnt):= P1;
                WeakCnt:= WeakCnt+1;
                ];
            ];
        if P1 < 1_000_000 then
            [StrongCnt0:= StrongCnt;  WeakCnt0:= WeakCnt];
        N:= N+2;
until   P1 >= 10_000_000;

Text(0, "First 36 strong primes:^M^J");
for N:= 0 to 36-1 do
    [NumOut(Strongs(N));  ChOut(0, ^ )];
Text(0, "^M^JStrong primes below 1,000,000: ");
NumOut(StrongCnt0);
Text(0, "^M^JStrong primes below 10,000,000: ");
NumOut(StrongCnt);
Text(0, "^M^JFirst 37 weak primes:^M^J");
for N:= 0 to 37-1 do
    [NumOut(Weaks(N));  ChOut(0, ^ )];
Text(0, "^M^JWeak primes below 1,000,000: ");
NumOut(WeakCnt0);
Text(0, "^M^JWeak primes below 10,000,000: ");
NumOut(WeakCnt);
CrLf(0);
]


var [const] BI=Import("zklBigNum");  // libGMP
const N=1e7;

pw,strong,weak := BI(1),List(),List();   // 32,0991  32,1751
ps:=(3).pump(List,'wrap{ pw.nextPrime().toInt() }).copy();  // rolling window
do{
   pp,p,pn := ps;
   if((z:=(pp.toFloat() + pn)/2)){  // 2,3,5 --> 3.5
      if(z>p)      weak  .append(p);
      else if(z<p) strong.append(p);
   }
   ps.pop(0); ps.append(pw.nextPrime().toInt());
}while(pn<=N);


V s = " \t \r \n String with spaces  \t  \r  \n  "
print(s.ltrim((‘ ’, "\t", "\r", "\n")).len)
print(s.rtrim((‘ ’, "\t", "\r", "\n")).len)
print(s.trim((‘ ’, "\t", "\r", "\n")).len)


DEFINE SPACE="32"
DEFINE TAB="127"
DEFINE NEWLINE="155"

BYTE FUNC IsWhitespace(CHAR c)
  IF c=SPACE OR c=TAB OR c=NEWLINE THEN
    RETURN (1)
  FI
RETURN (0)

PROC Strip(CHAR ARRAY src,dst BYTE head,tail)
  BYTE i,first,last

  first=1
  last=src(0)

  IF head THEN
    WHILE first<=last
    DO
      IF IsWhitespace(src(first))=0 THEN
        EXIT
      FI
      first==+1
    OD
  FI

  IF tail THEN
    WHILE last>=first
    DO
      IF IsWhitespace(src(last))=0 THEN
        EXIT
      FI
      last==-1
    OD
  FI

  IF first>last THEN
    dst(0)=0
  ELSE
    SCopyS(dst,src,first,last)
  FI
RETURN

PROC Main()
  CHAR ARRAY src="    Action!    ",dst(20)

  src(2)=NEWLINE src(13)=TAB

  PrintF("Original string:%E""%S""%E%E",src)
  Strip(src,dst,1,0)
  PrintF("Trim leading whitespaces:%E""%S""%E%E",dst)
  Strip(src,dst,0,1)
  PrintF("Trim trailing whitespaces:%E""%S""%E%E",dst)
  Strip(src,dst,1,1)
  PrintF("Trim leading and trailing whitespaces:""%S""%E%E",dst)
RETURN


with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
procedure StripDemo is
   str : String := "     Jabberwocky     ";
begin
   Put_Line ("'" & Trim (str, Left) & "'");
   Put_Line ("'" & Trim (str, Right) & "'");
   Put_Line ("'" & Trim (str, Both) & "'");
end StripDemo;


# returns "text" with leading non-printing characters removed #
PROC trim leading whitespace = ( STRING text )STRING:
BEGIN

    INT pos := LWB text;

    WHILE
        IF pos > UPB text
        THEN
            FALSE
        ELSE
            text[ pos ] <= " "
        FI
    DO
        pos +:= 1
    OD;

    text[ pos : ]
END; # trim leading whitespace #

# returns "text" with trailing non-printing characters removed #
PROC trim trailing whitespace = ( STRING text )STRING:
BEGIN

    INT pos := UPB text;

    WHILE
        IF pos < LWB text
        THEN
            FALSE
        ELSE
            text[ pos ] <= " "
        FI
    DO
        pos -:= 1
    OD;

    text[ : pos ]
END; # trim trailing whitespace #

# returns "text" with leading and trailing non-printing characters removed #
PROC trim whitespace = ( STRING text )STRING:
BEGIN
    trim trailing whitespace( trim leading whitespace( text ) )
END; # trim whitespace #

main:(
    STRING test = "   leading and trailing spaces surrounded this text   ";

    print( ( "trim  leading: """ + trim leading whitespace ( test ) + """", newline ) );
    print( ( "trim trailing: """ + trim trailing whitespace( test ) + """", newline ) );
    print( ( "trim     both: """ + trim whitespace         ( test ) + """", newline ) )
)


use framework "Foundation" -- "OS X" Yosemite onwards, for NSRegularExpression

-- STRIP WHITESPACE ----------------------------------------------------------

-- isSpace :: Char -> Bool
on isSpace(c)
    ((length of c) = 1) and regexTest("\\s", c)
end isSpace

-- stripStart :: Text -> Text
on stripStart(s)
    dropWhile(isSpace, s) as text
end stripStart

-- stripEnd :: Text -> Text
on stripEnd(s)
    dropWhileEnd(isSpace, s) as text
end stripEnd

-- strip :: Text -> Text
on strip(s)
    dropAround(isSpace, s) as text
end strip

-- TEST ----------------------------------------------------------------------
on run
    set strText to "  \t\t \n \r    Much Ado About Nothing \t \n \r  "

    script arrowed
        on |λ|(x)
            "-->" & x & "<--"
        end |λ|
    end script

    map(arrowed, [stripStart(strText), stripEnd(strText), strip(strText)])

    --     {"-->Much Ado About Nothing
    --
    --   <--", "-->
    --
    --     Much Ado About Nothing<--", "-->Much Ado About Nothing<--"}
end run

-- GENERIC FUNCTIONS ---------------------------------------------------------

-- dropAround :: (Char -> Bool) -> [a] -> [a]
on dropAround(p, xs)
    dropWhile(p, dropWhileEnd(p, xs))
end dropAround

-- dropWhile :: (a -> Bool) -> [a] -> [a]
on dropWhile(p, xs)
    tell mReturn(p)
        set lng to length of xs
        set i to 1
        repeat while i ≤ lng and |λ|(item i of xs)
            set i to i + 1
        end repeat
    end tell
    if i ≤ lng then
        items i thru lng of xs
    else
        {}
    end if
end dropWhile

-- dropWhileEnd :: (a -> Bool) -> [a] -> [a]
on dropWhileEnd(p, xs)
    tell mReturn(p)
        set i to length of xs
        repeat while i > 0 and |λ|(item i of xs)
            set i to i - 1
        end repeat
    end tell
    if i > 0 then
        items 1 thru i of xs
    else
        {}
    end if
end dropWhileEnd

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- regexTest :: RegexPattern -> String -> Bool
on regexTest(strRegex, str)
    set ca to current application
    set oString to ca's NSString's stringWithString:str
    ((ca's NSRegularExpression's regularExpressionWithPattern:strRegex ¬
        options:((ca's NSRegularExpressionAnchorsMatchLines as integer)) ¬
        |error|:(missing value))'s firstMatchInString:oString options:0 ¬
        range:{location:0, |length|:oString's |length|()}) is not missing value
end regexTest


str: "     Hello World     "

print [pad "strip all:"      15  ">" strip str       "<"]
print [pad "strip leading:"  15  ">" strip.start str "<"]
print [pad "strip trailing:" 15  ">" strip.end str   "<"]


string := "   abc   "
MsgBox % clipboard := "<" LTrim(string) ">`n<" RTrim(string) ">`n<" . Trim(string) ">"


function trimleft(str   ,c, out, arr) {
    c = split(str, arr, "")
    for ( i = match(str, /[[:graph:]]/); i <= c; i++)
          out = out arr[i]
    return out
}

function reverse(str    ,n, tmp, j, out) {
    n = split(str, tmp, "")
    for (j = n; j > 0; j--)
        out = out tmp[j]
    return out
}

function trimright(str) {
    return reverse(trimleft(reverse(str)))
}

function trim(str) {
    return trimright(trimleft(str))
}

BEGIN {
    str = " \x0B\t\r\n \xA0 Hellö \xA0\x0B\t\r\n "
    print "string  = |" str "|"
    print "left    = |" trimleft(str) "|"
    print "right   = |" trimright(str) "|"
    print "both    = |" trim(str) "|"
}


'---Remove leading whitespace
PRINT CHOP$("     String with spaces     "," ",1)

'---Remove trailing whitespace
PRINT CHOP$("     String with spaces     "," ",2)

'---Remove both leading and trailing whitespace
PRINT CHOP$("     String with spaces     "," ",0)


 mystring$=ltrim(mystring$)           ' remove leading whitespace
 mystring$=rtrim(mystring$)           ' remove trailing whitespace
 mystring$=ltrim(rtrim(mystring$))    ' remove both leading and trailing whitespace


      REM Remove leading whitespace:
      WHILE ASC(A$)<=32 A$ = MID$(A$,2) : ENDWHILE

      REM Remove trailing whitespace:
      WHILE ASC(RIGHT$(A$))<=32 A$ = LEFT$(A$) : ENDWHILE

      REM Remove both leading and trailing whitespace:
      WHILE ASC(A$)<=32 A$ = MID$(A$,2) : ENDWHILE
      WHILE ASC(RIGHT$(A$))<=32 A$ = LEFT$(A$) : ENDWHILE


( ( ltrim
  =   s
    .   @( !arg
         :   ?
             (   ( %@
                 : ~( " "
                    | \a
                    | \b
                    | \n
                    | \r
                    | \t
                    | \v
                    )
                 )
                 ?
             : ?s
             )
         )
      & !s
  )
& (rtrim=.rev$(ltrim$(rev$!arg)))
& (trim=.rev$(ltrim$(rev$(ltrim$!arg))))
& (string="   \a  Hear
	 the sound?
\v

\r
")
& out$(str$("Input:[" !string "]"))
& out$(str$("ltrim:[" ltrim$!string "]"))
& out$(str$("rtrim:[" rtrim$!string "]"))
& out$(str$("trim :[" trim$!string "]"))
&
);


blsq ) "  this is a string  "t[
"this is a string  "
blsq ) "  this is a string  "t]
"  this is a string"
blsq ) "  this is a string  "tt
"this is a string"


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char *rtrim(const char *s)
{
  while( isspace(*s) || !isprint(*s) ) ++s;
  return strdup(s);
}

char *ltrim(const char *s)
{
  char *r = strdup(s);
  if (r != NULL)
  {
    char *fr = r + strlen(s) - 1;
    while( (isspace(*fr) || !isprint(*fr) || *fr == 0) && fr >= r) --fr;
    *++fr = 0;
  }
  return r;
}

char *trim(const char *s)
{
  char *r = rtrim(s);
  char *f = ltrim(r);
  free(r);
  return f;
}

const char *a = "     this is a string      ";

int main()
{
  char *b = rtrim(a);
  char *c = ltrim(a);
  char *d = trim(a);

  printf("'%s'\n'%s'\n'%s'\n", b, c, d);

  free(b);
  free(c);
  free(d);
  return 0;
}


using System;

public class TrimExample
{
    public static void Main(String[] args)
    {
        const string toTrim = " Trim me ";
        Console.WriteLine(Wrap(toTrim.TrimStart()));
        Console.WriteLine(Wrap(toTrim.TrimEnd()));
        Console.WriteLine(Wrap(toTrim.Trim()));
    }

    private static string Wrap(string s)
    {
        return "'" + s + "'";
    }
}


#include <boost/algorithm/string.hpp>
#include <string>
#include <iostream>

int main( ) {
   std::string testphrase( "    There are unwanted blanks here!    " ) ;
   std::string lefttrimmed = boost::trim_left_copy( testphrase ) ;
   std::string righttrimmed = boost::trim_right_copy( testphrase ) ;
   std::cout << "The test phrase is :" << testphrase << "\n" ;
   std::cout << "Trimmed on the left side :" << lefttrimmed << "\n" ;
   std::cout << "Trimmed on the right side :" << righttrimmed << "\n" ;
   boost::trim( testphrase ) ;
   std::cout << "Trimmed on both sides :" <<  testphrase  << "\n" ;
   return 0 ;
}


(use 'clojure.string)
(triml "   my string   ")
=> "my string   "
(trimr "   my string   ")
=> "   my string"
(trim " \t\r\n my string \t\r\n  ")
=> "my string"


DISPLAY "'" FUNCTION TRIM(str, LEADING) "'"
DISPLAY "'" FUNCTION TRIM(str, TRAILING) "'"
DISPLAY "'" FUNCTION TRIM(str) "'"


; Common whitespace characters
(defvar *whitespace* '(#\Space #\Newline #\Tab))

(defvar str "   foo bar     baz  ")

(string-trim *whitespace* str)
; -> "foo bar     baz"

(string-left-trim *whitespace* str)
; -> "foo bar     baz  "

(string-right-trim *whitespace* str)
; -> "   foo bar     baz"

; Whitespace characters defined by Unicode for
; implementations which support it (e.g. CLISP, SBCL).
; (see http://www.unicode.org/Public/UCD/latest/ucd/PropList.txt)
(defvar *unicode-whitespace*
  '(#\u0009 #\u000a #\u000b #\u000c #\u000d
    #\u0020 #\u0085 #\u00a0 #\u1680 #\u2000
    #\u2001 #\u2002 #\u2003 #\u2004 #\u2005
    #\u2006 #\u2007 #\u2008 #\u2009 #\u200a
    #\u2028 #\u2029 #\u202f #\u205f #\u3000))

(defvar unicode-str
  (format nil "~C~Cfoo~Cbar~Cbaz~C~C"
          #\u2000 #\u2003 #\u0020 #\u00a0 #\u0009 #\u202f))

(string-trim *unicode-whitespace* unicode-str)
; -> "foo bar baz"

(string-left-trim *unicode-whitespace* unicode-str)
; -> "foo bar baz     "

(string-right-trim *unicode-whitespace* unicode-str)
; -> "  foo bar baz"


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))


def strip_whitepace(s)
    puts s.lstrip()
    puts s.rstrip()
    puts s.strip()
end

strip_whitepace("\t hello \t")
# => hello
# =>      hello
# => hello


import std.stdio, std.string;

void main() {
    auto s = " \t \r \n String with spaces  \t  \r  \n  ";
    assert(s.stripLeft() == "String with spaces  \t  \r  \n  ");
    assert(s.stripRight() == " \t \r \n String with spaces");
    assert(s.strip() == "String with spaces");
}


with Ada.Strings.Fixed;
with Ada.Strings.Unbounded;
with Ada.Text_IO;
with Ada.Command_Line;

procedure Strip is
   use Ada.Strings.Unbounded;
   procedure Print_Usage is
   begin
      Ada.Text_IO.Put_Line ("Usage:");
      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line ("   strip <file> [<opening> [<closing>]]");
      Ada.Text_IO.New_Line;
      Ada.Text_IO.Put_Line ("      file: file to strip");
      Ada.Text_IO.Put_Line ("      opening: string for opening comment");
      Ada.Text_IO.Put_Line ("      closing: string for closing comment");
      Ada.Text_IO.New_Line;
   end Print_Usage;

   Opening_Pattern : Unbounded_String := To_Unbounded_String ("/*");
   Closing_Pattern : Unbounded_String := To_Unbounded_String ("*/");
   Inside_Comment  : Boolean          := False;

   function Strip_Comments (From : String) return String is
      use Ada.Strings.Fixed;
      Opening_Index : Natural;
      Closing_Index : Natural;
      Start_Index   : Natural := From'First;
   begin
      if Inside_Comment then
         Start_Index :=
            Index (Source => From, Pattern => To_String (Closing_Pattern));
         if Start_Index < From'First then
            return "";
         end if;
         Inside_Comment := False;
         Start_Index    := Start_Index + Length (Closing_Pattern);
      end if;
      Opening_Index :=
         Index
           (Source  => From,
            Pattern => To_String (Opening_Pattern),
            From    => Start_Index);
      if Opening_Index < From'First then
         return From (Start_Index .. From'Last);
      else
         Closing_Index :=
            Index
              (Source  => From,
               Pattern => To_String (Closing_Pattern),
               From    => Opening_Index + Length (Opening_Pattern));
         if Closing_Index > 0 then
            return From (Start_Index .. Opening_Index - 1) &
                   Strip_Comments
                      (From (
               Closing_Index + Length (Closing_Pattern) .. From'Last));
         else
            Inside_Comment := True;
            return From (Start_Index .. Opening_Index - 1);
         end if;
      end if;
   end Strip_Comments;

   File : Ada.Text_IO.File_Type;
begin
   if Ada.Command_Line.Argument_Count < 1
     or else Ada.Command_Line.Argument_Count > 3
   then
      Print_Usage;
      return;
   end if;
   if Ada.Command_Line.Argument_Count > 1 then
      Opening_Pattern := To_Unbounded_String (Ada.Command_Line.Argument (2));
      if Ada.Command_Line.Argument_Count > 2 then
         Closing_Pattern :=
            To_Unbounded_String (Ada.Command_Line.Argument (3));
      else
         Closing_Pattern := Opening_Pattern;
      end if;
   end if;
   Ada.Text_IO.Open
     (File => File,
      Mode => Ada.Text_IO.In_File,
      Name => Ada.Command_Line.Argument (1));
   while not Ada.Text_IO.End_Of_File (File => File) loop
      declare
         Line : constant String := Ada.Text_IO.Get_Line (File);
      begin
         Ada.Text_IO.Put_Line (Strip_Comments (Line));
      end;
   end loop;
   Ada.Text_IO.Close (File => File);
end Strip;


program StripWhitespace;

{$APPTYPE CONSOLE}

uses SysUtils;

const
  TEST_STRING = '     String with spaces     ';
begin
  Writeln('"' + TEST_STRING + '"');
  Writeln('"' + TrimLeft(TEST_STRING) + '"');
  Writeln('"' + TrimRight(TEST_STRING) + '"');
  Writeln('"' + Trim(TEST_STRING) + '"');
end.


const TEST_STRING = '     String with spaces     ';

PrintLn('"' + TEST_STRING + '"');
PrintLn('"' + TrimLeft(TEST_STRING) + '"');
PrintLn('"' + TrimRight(TEST_STRING) + '"');
PrintLn('"' + Trim(TEST_STRING) + '"');


(define witt
   "                 The limits of my world are the limits of my langage.         ")
(string->html (string-trim witt))
   → "The limits of my world are the limits of my langage."
(string->html (string-trim-left witt))
   → "The limits of my world are the limits of my langage.         "
(string->html (string-trim-right witt))
   → "                 The limits of my world are the limits of my langage."


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.


code =
(
 /**
   * Some comments
   * longer comments here that we can parse.
   *
   * Rahoo
   */
   function subroutine() {
    a = /* inline comment */ b + c ;
   }
   /*/ <-- tricky comments */

   /**
    * Another comment.
    */
    function something() {
    }
)
;Open-Close Comment delimiters
	openC:="/*"
	closeC:="*/"
;Make it "Regex-Safe"
	openC:=RegExReplace(openC,"(\*|\^|\?|\\|\+|\.|\!|\{|\}|\[|\]|\$|\|)","\$0")
	closeC:=RegExReplace(closeC,"(\*|\^|\?|\\|\+|\.|\!|\{|\}|\[|\]|\$|\|)","\$0")
;Display final result
	MsgBox % sCode := RegExReplace(code,"s)(" . openC . ").*?(" . closeC . ")")


# 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)
}


import extensions;

public program()
{
    var toTrim := " Trim me ";
    console.printLine("'", toTrim.trimLeft(),"'");
    console.printLine("'", toTrim.trimRight(),"'");
    console.printLine("'", toTrim.trim(),"'");
}


str = "\n \t foo \n\t bar \t \n"
IO.inspect String.strip(str)
IO.inspect String.rstrip(str)
IO.inspect String.lstrip(str)


(string-trim-left "    left center right    ")  ;=> "left center right    "
(string-trim-right "    left center right    ") ;=> "    left center right"
(string-trim  "    left center right    ")      ;=> "left center right"


% Implemented by Arjun Sunel
1> string:strip("   Hello World!   ", left). %remove leading whitespaces
"Hello World!   "

2> string:strip("   Hello World!   ", right). % remove trailing whitespaces
"   Hello World!"

3> string:strip("   Hello World!   ", both).  % remove both leading and trailing whitespace
"Hello World!"


      infile$ = "C:\sample.c"
      outfile$ = "C:\stripped.c"

      PROCstripblockcomments(infile$, outfile$, "/*", "*/")
      END

      DEF PROCstripblockcomments(infile$, outfile$, start$, finish$)
      LOCAL infile%, outfile%, comment%, test%, A$

      infile% = OPENIN(infile$)
      IF infile%=0 ERROR 100, "Could not open input file"
      outfile% = OPENOUT(outfile$)
      IF outfile%=0 ERROR 100, "Could not open output file"

      WHILE NOT EOF#infile%
        A$ = GET$#infile% TO 10
        REPEAT
          IF comment% THEN
            test% = INSTR(A$, finish$)
            IF test% THEN
              A$ = MID$(A$, test% + LEN(finish$))
              comment% = FALSE
            ENDIF
          ELSE
            test% = INSTR(A$, start$)
            IF test% THEN
              BPUT#outfile%, LEFT$(A$, test%-1);
              A$ = MID$(A$, test% + LEN(start$))
              comment% = TRUE
            ENDIF
          ENDIF
        UNTIL test%=0
        IF NOT comment% BPUT#outfile%, A$
      ENDWHILE

      CLOSE #infile%
      CLOSE #outfile%
      ENDPROC


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const char *ca = "/*", *cb = "*/";
int al = 2, bl = 2;

char *loadfile(const char *fn) {
    FILE *f = fopen(fn, "rb");
    int l;
    char *s;

    if (f != NULL) {
	fseek(f, 0, SEEK_END);
	l = ftell(f);
	s = malloc(l+1);
	rewind(f);
	if (s)
	    fread(s, 1, l, f);
	fclose(f);
    }
    return s;
}

void stripcomments(char *s) {
    char *a, *b;
    int len = strlen(s) + 1;

    while ((a = strstr(s, ca)) != NULL) {
	b = strstr(a+al, cb);
	if (b == NULL)
	    break;
	b += bl;
	memmove(a, b, len-(b-a));
    }
}

int main(int argc, char **argv) {
    const char *fn = "input.txt";
    char *s;

    if (argc >= 2)
	fn = argv[1];
    s = loadfile(fn);
    if (argc == 4) {
	al = strlen(ca = argv[2]);
	bl = strlen(cb = argv[3]);
    }
    stripcomments(s);
    puts(s);
    free(s);
    return 0;
}


include std/console.e
include std/text.e

sequence removables = " \t\n\r\x05\u0234\" "
sequence extraSeq = "  \x05\r \" A  B  C  \n \t\t  \u0234 \r\r \x05   "

extraSeq = trim(extraSeq,removables) --the work is done by the trim function

--only output programming next :
printf(1, "String Trimmed is now: %s \r\n", {extraSeq} ) --print the resulting string to screen

for i = 1 to length(extraSeq) do --loop over each character in the sequence.
    printf(1, "String element %d", i) --to look at more detail,
    printf(1, " : %d\r\n", extraSeq[i])--print integer values(ascii) of the string.
end for

any_key()


[<EntryPoint>]
let main args =
    printfn "%A" (args.[0].TrimStart())
    printfn "%A" (args.[0].TrimEnd())
    printfn "%A" (args.[0].Trim())
    0


USE: unicode
"     test string    " [ blank? ] trim        ! leading and trailing
"     test string    " [ blank? ] trim-head   ! only leading
"     test string    " [ blank? ] trim-tail   ! only trailing


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;
        }
    }


#include <string>
#include <iostream>
#include <iterator>
#include <fstream>
#include <boost/regex.hpp>

int main( ) {
    std::ifstream codeFile( "samplecode.txt" ) ;
    if ( codeFile ) {
       boost::regex commentre( "/\\*.*?\\*/" ) ;//comment start and end, and as few characters in between as possible
       std::string my_erase( "" ) ;             //erase them
       std::string stripped ;
       std::string code( (std::istreambuf_iterator<char>( codeFile ) ) ,
	     std::istreambuf_iterator<char>( ) ) ;
       codeFile.close( ) ;
       stripped = boost::regex_replace( code , commentre , my_erase ) ;
       std::cout << "Code unstripped:\n" << stripped << std::endl ;
       return 0 ;
    }
    else {
       std::cout << "Could not find code file!" << std::endl ;
       return 1 ;
    }
}


: -leading ( addr len -- addr' len' ) \ called "minus-leading"
    begin
      over [email protected] bl =  \ fetch character at addr, test if blank (space)
    while
     \ cut 1 leading character by incrementing address & decrementing length
      1 /string      \ "cut-string"
   repeat ;


' FB 1.05.0 Win64

Const whitespace = !" \t\n\v\f\r"

Dim s  As String = !"  \tRosetta Code \v\f\r\n"
Dim s1 As String = LTrim (s, Any whitespace)
Dim s2 As String = RTrim (s, Any whitespace)
Dim s3 As String = Trim  (s, Any whitespace)

' Under Windows console :
' "vertical tab" displays as ♂
' "form feed" displays as ♀
' the other whitespace characters do what it says on the tin

Print "Untrimmed"         , "=> "; s
Print "Left Trimmed"      , "=> "; s1
Print "Right Trimmed"     , "=> "; s2
Print "Fully Trimmed"     , "=> "; s3
Print
Print "Untrimmed"         , "=>  Length = "; Len(s)
Print "Left trimmed"      , "=>  Length = "; Len(s1)
Print "Right trimmed"     , "=>  Length = "; Len(s2)
Print "Fully trimmed"     , "=>  Length = "; Len(s3)
Sleep


(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)]
    (loop [out "", txt txt, delim-count 0] ; delim-count is needed to handle nested comments
      (let [[hdtxt resttxt] (split-at (count opener) txt)] ; This splits "/* blah blah */" into hdtxt="/*" and restxt="blah blah */"
	(printf "hdtxt=%8s resttxt=%8s out=%8s txt=%16s delim-count=%s\n" (apply str hdtxt) (apply str resttxt) out (apply str txt) delim-count)
	(cond
	 (empty? hdtxt)    (str out (apply str txt))
	 (= (apply str hdtxt) opener) (recur out resttxt (inc delim-count))
	 (= (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))))))


import std.algorithm, std.regex;

string[2] separateComments(in string txt,
                           in string cpat0, in string cpat1) {
    int[2] plen; // to handle /*/
    int i, j; // cursors
    bool inside; // is inside comment?

    // pre-compute regex here if desired
    //auto r0 = regex(cpat0);
    //auto r1 = regex(cpat1);
    //enum rct = ctRegex!(r"\n|\r");

    bool advCursor() {
        auto mo = match(txt[i .. $], inside ? cpat1 : cpat0);
        if (mo.empty)
            return false;
        plen[inside] = max(0, plen[inside], mo.front[0].length);
        j = i + mo.pre.length; // got comment head
        if (inside)
            j += mo.front[0].length; // or comment tail

        // special adjust for \n\r
        if (!match(mo.front[0], r"\n|\r").empty)
            j--;
        return true;
    }

    string[2] result;
    while (true) {
        if (!advCursor())
            break;
        result[inside] ~= txt[i .. j]; // save slice of result

        // handle /*/ pattern
        if (inside && (j - i < plen[0] + plen[1])) {
            i = j;
            if (!advCursor())
                break;
            result[inside] ~= txt[i .. j]; // save result again
        }

        i = j; // advance cursor
        inside = !inside; // toggle search type
    }

    if (inside)
        throw new Exception("Mismatched Comment");
    result[inside] ~= txt[i .. $]; // save rest(non-comment)
    return result;
}

void main() {
    import std.stdio;

    static void showResults(in string e, in string[2] pair) {
        writeln("===Original text:\n", e);
        writeln("\n\n===Text without comments:\n", pair[0]);
        writeln("\n\n===The stripped comments:\n", pair[1]);
    }

    // First example ------------------------------
    immutable ex1 = `  /**
   * Some comments
   * longer comments here that we can parse.
   *
   * Rahoo
   */
   function subroutine() {
    a = /* inline comment */ b + c ;
   }
   /*/ <-- tricky comments */

   /**
    * Another comment.
    */
    function something() {
    }`;

    showResults(ex1, separateComments(ex1, `/\*`, `\*/`));

    // Second example ------------------------------
    writeln("\n");
    immutable ex2 = "apples, pears # and bananas
apples, pears; and bananas ";  // test for line comment

    showResults(ex2, separateComments(ex2, `#|;`, `[\n\r]|$`));
}


F stripped(s)
   R s.filter(i -> Int(i.code) C 32..126).join(‘’)

print(stripped("\ba\u0000b\n\rc\fd\xc3"))


window 1

CFCharacterSetRef set, invSet
CFStringRef       s, s1, s2, s3
NSUInteger        index
CFRange           range

set = fn CharacterSetWhitespaceAndNewlineSet
invSet = fn CharacterSetInvertedSet( set )

text ,,,,, 200

s = @"     a string        "// 5 leading spaces, 8 trailing spaces
print s, len(s)@" chars"

// left trim
index = 0
range = fn StringRangeOfCharacterFromSet( s, invSet )
if ( range.location != NSNotFound ) then index = range.location
s1 = fn StringSubstringFromIndex( s, index )
print s1, len(s1)@" chars"

// right trim
index = len(s)
range = fn StringRangeOfCharacterFromSetWithOptions( s, invSet, NSBackwardsSearch )
if ( range.location != NSNotFound ) then index = range.location + 1
s2 = fn StringSubstringToIndex( s, index )
print s2, len(s2)@" chars"

// trim
s3 = fn StringByTrimmingCharactersInSet( s, set )
print s3, len(s3)@" chars"

HandleEvents


Public Sub Main()
Dim sString As String = "    Hello world!    "

Print sString & "\tString length = " & Len(sString) & " - Original string"
Print LTrim(sString) & "\tString length = " & Len(LTrim(sString)) & " - String with leading whitespace removed"
Print RTrim(sString) & "\tString length = " & Len(RTrim(sString)) & " - String with trailing whitespace removed"
Print Trim(sString) & "\t\tString length = " & Len(Trim(sString)) & " - String with both leading and trailing whitespace removed"

End


package main

import (
    "fmt"
    "strings"
    "unicode"
)

var simple = `
    simple   `

func main() {
    show("original", simple)
    show("leading ws removed", strings.TrimLeftFunc(simple, unicode.IsSpace))
    show("trailing ws removed", strings.TrimRightFunc(simple, unicode.IsSpace))
    // equivalent to strings.TrimFunc(simple, unicode.IsSpace)
    show("both removed", strings.TrimSpace(simple))
}

func show(label, str string) {
    fmt.Printf("%s: |%s| %v\n", label, str, []rune(str))
}


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.


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


   .model small
   .stack 1024
   .data
StringStrip db "abc",13,10,8,7,"def",90h
   .code

start:

	mov ax,@data
	mov ds,ax

	mov ax,@code
	mov es,ax

	mov ax,03h
	int 10h      ;clear screen

	mov si,offset StringStrip
	call PrintString_PartiallyStripped

	call NewLine

	mov si,offset StringStrip
	call PrintString_Stripped

	mov ax,4C00h
	int 21h       ;return to DOS

PrintString_Stripped:
;prints a null-terminated string
;all other control codes are stripped.
	lodsb
	cmp al,0
	jz Terminated
	;not equal to zero
	cmp al,21h		 ; if (AL < 21h)
	jb PrintString_Stripped  ;skip this character and keep going
	cmp al,7Fh		 ; if (AL >= 7Fh)
	jae PrintString_Stripped ;skip this character and keep going
	        mov ah,02h
                mov dl,al
		int 21h           ;prints character in DL to screen
	jmp PrintString_Stripped
Terminated:
	ret
PrintString_PartiallyStripped:
;strips control codes but not extended ascii.
;The null terminator isn't stripped of course.
	lodsb
	cmp al,0
	jz Terminated_PartiallyStripped
	cmp al,21h
	jb PrintString_PartiallyStripped
	cmp al,7Fh
	je PrintString_PartiallyStripped ;delete counts as a control code
		mov ah,02h
		mov dl,al
		int 21h
	jmp PrintString_PartiallyStripped
Terminated_PartiallyStripped:
	ret

NewLine:
        mov ah,02h
        mov dl,13    ;carriage return
        int 10h
        mov ah,02h
        mov dl,10    ;line feed
        int 10h
        ret
        end start


BYTE FUNC IsAscii(CHAR c)
  IF c<32 OR c>124 OR c=96 OR c=123 THEN
    RETURN (0)
  FI
RETURN (1)

PROC Strip(CHAR ARRAY src,dst)
  CHAR c
  BYTE i

  dst(0)=0
  FOR i=1 TO src(0)
  DO
    c=src(i)
    IF IsAscii(c) THEN
      dst(0)==+1
      dst(dst(0))=c
    FI
  OD
RETURN

PROC Main()
  CHAR ARRAY
    src(20)=[16 0 16 96 123 'a 'b 'c 131 27 30 '1 '2 '3 4 1 20],
    dst(20)

  PrintF("Original string: ""%S""%E",src)
  Strip(src,dst)
  PrintF("Stripped string: ""%S""%E",dst)
RETURN


//Grape setup to get library
@Grab('org.apache.commons:commons-lang3:3.0.1')
import static org.apache.commons.lang3.StringUtils.*

def abc = '\r\n\t  abc  \r\n\t'

def printTest = {
    println ('|' + it + '|')
}

println 'Unstripped\n------------'
printTest abc

println '============\n\nStripped\n------------'
printTest strip(abc)

println '============\n\nLeft Stripped\n------------'
printTest stripStart(abc, null)

println '============\n\nRight Stripped\n------------'
printTest stripEnd(abc, null)
println '============'


import Data.Char (isSpace)
import Data.List (dropWhileEnd)

trimLeft :: String -> String
trimLeft = dropWhile isSpace

trimRight :: String -> String
trimRight = dropWhileEnd isSpace

trim :: String -> String
trim = trimLeft . trimRight


: strip-block-comments ( string -- string )
  R/ /\*.*?\*\// "" re-replace ;


      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.
       CHARACTER*(*) THIS,THAT	!Starting and ending markers.
       INTEGER LOTS			!How long is a piece of string?
       PARAMETER (LOTS = 6666)		!This should do.
       CHARACTER*(LOTS) ACARD,ALINE	!Scratchpads.
       INTEGER LC,LL,L		!Lengths.
       INTEGER L1,L2		!Scan fingers.
       INTEGER NC,NL		!Might as well count records read and written.
       LOGICAL BLAH		!A state: in or out of a block comment.
       INTEGER MSG,KBD,INF,OUT		!I/O unit numbers.
       COMMON /IODEV/MSG,KBD,INF,OUT	!Thus.
        NC = 0		!No cards read in.
        NL = 0		!No lines written out.
        BLAH = .FALSE.	!And we're not within a comment.
Chug through the input.
   10   READ(INF,11,END = 100) LC,ACARD(1:MIN(LC,LOTS))	!Yum.
   11   FORMAT (Q,A)		!Sez: how much remains (Q), then, characters (A).
        NC = NC + 1		!A card has been read.
        IF (LC.GT.LOTS) THEN	!Paranoia.
          WRITE (MSG,12) NC,LC,LOTS	!Scream.
   12     FORMAT ("Record ",I0," has length ",I0,"! My limit is ",I0)
          LC = LOTS			!Stay calm, and carry on.
        END IF			!None of this should happen.
Chew through ACARD according to mood.
        LL = 0		!No output yet.
        L2 = 0		!Syncopation. Where the previous sniff ended.
   20   L1 = L2 + 1	!The start of what we're looking at.
        IF (L1.LE.LC) THEN	!Anything left?
          L2 = L1		!Yes. This is the probe.
          IF (BLAH) THEN	!So, what's our mood?
   21       IF (L2 + LEN(THAT) - 1 .LE. LC) THEN	!We're skipping stuff.
              IF (ACARD(L2:L2 + LEN(THAT) - 1).EQ.THAT) THEN	!An ender yet?
                BLAH = .FALSE.		!Yes!
                L2 = L2 + LEN(THAT) - 1	!Finger its final character.
                GO TO 20		!And start a new advance.
              END IF		!But if that wasn't an ender,
              L2 = L2 + 1	!Advance one.
              GO TO 21		!And try again.
            END IF	!By here, insufficient text remains to match THAT, so we're finished with ACARD.
           ELSE		!Otherwise, if we're not in a comment, we're looking at grist.
   22       IF (L2 + LEN(THIS) - 1 .LE. LC) THEN	!Enough text to match a comment starter?
              IF (ACARD(L2:L2 + LEN(THIS) - 1).EQ.THIS) THEN	!Yes. Does it?
                BLAH = .TRUE.		!Yes!
                L = L2 - L1		!Recalling where this state started.
                ALINE(LL + 1:LL + L) = ACARD(L1:L2 - 1)	!Copy the non-BLAH text.
                LL = LL + L		!L2 fingers the first of THIS.
                L2 = L2 + LEN(THIS) - 1	!Finger the last matching THIS.
                GO TO 20		!And resume.
              END IF		!But if that wasn't a comment starter,
              L2 = L2 + 1	!Advance one.
              GO TO 22		!And try again.
            END IF	!But if there remains insufficient to match THIS
            L = LC - L1 + 1	!Then the remainder of the line is grist.
            ALINE(LL + 1:LL + L) = ACARD(L1:LC)	!So grab it.
            LL = LL + L		!And count it in.
          END IF	!By here, we're finished witrh ACARD.
        END IF	!So much for ACARD.
Cast forth some output.
        IF (LL.GT.0) THEN	!If there is any.
          WRITE (OUT,23) ALINE(1:LL)	!There is.
   23     FORMAT (">",A,"<") 		!Just text, but with added bounds.
          NL = NL + 1			!Count a line.
        END IF        		!So much for output.
        GO TO 10	!Perhaps there is some more input.
Completed.
  100   WRITE (MSG,101) NC,NL	!Be polite.
  101   FORMAT (I0," read, ",I0," written.")
      END       !No attention to context, such as quoted strings.

      PROGRAM TEST
      INTEGER MSG,KBD,INF,OUT
      COMMON /IODEV/MSG,KBD,INF,OUT
      KBD = 5
      MSG = 6
      INF = 10
      OUT = 11
      OPEN (INF,FILE="Source.txt",STATUS="OLD",ACTION="READ")
      OPEN (OUT,FILE="Src.txt",STATUS="REPLACE",ACTION="WRITE")

      CALL UNBLOCK("/*","*/")

      END	!All open files are closed on exit..


with Ada.Text_IO;

procedure Strip_ASCII is

   Full: String := 'a' & Character'Val(11) & 'b' & Character'Val(166) &
                   'c' & Character'Val(127) & Character'Val(203) &
                   Character'Val(202) & "de";
   -- 5 ordinary characters ('a' .. 'e')
   -- 2 control characters (11, 127); note that 11 is the "vertical tab"
   -- 3 extended characters (166, 203, 202)

   function Filter(S:     String;
                   From:  Character := ' ';
                   To:    Character := Character'Val(126);
                   Above: Character := Character'Val(127)) return String is
   begin
      if S'Length = 0 then
         return "";
      elsif (S(S'First) >= From and then S(S'First) <= To) or else S(S'First) > Above then
         return S(S'First) & Filter(S(S'First+1 .. S'Last), From, To, Above);
      else
         return Filter(S(S'First+1 .. S'Last), From, To, Above);
      end if;
   end Filter;

   procedure Put_Line(Text, S: String) is
   begin
      Ada.Text_IO.Put_Line(Text & " """ & S & """, Length:" & Integer'Image(S'Length));
   end Put_Line;

begin
   Put_Line("The full string :", Full);
   Put_Line("No Control Chars:", Filter(Full)); -- default values for From, To, and Above
   Put_Line("Neither_Extended:", Filter(Full, Above => Character'Last)); -- defaults for From and To
end Strip_ASCII;


# remove control characters and optionally extended characters from the string text  #
# assums ASCII is the character set                                                  #
PROC strip characters = ( STRING text, BOOL strip extended )STRING:
     BEGIN
         # we build the result in a []CHAR and convert back to a string at the end #
         INT text start = LWB text;
         INT text max   = UPB text;
         [ text start : text max ]CHAR result;
         INT result pos := text start;
         FOR text pos FROM text start TO text max DO
             INT ch := ABS text[ text pos ];
             IF ( ch >= 0 AND ch <= 31 ) OR ch = 127 THEN
                 # control character #
                 SKIP
             ELIF strip extended AND ( ch > 126 OR ch < 0 ) THEN
                 # extened character and we don't want them #
                 SKIP
             ELSE
                 # include this character #
                 result[ result pos ] := REPR ch;
                 result pos +:= 1
             FI
         OD;
         result[ text start : result pos - 1 ]
     END # strip characters # ;

# test the control/extended character stripping procedure #
STRING t = REPR 2 + "abc" + REPR 10 + REPR 160 + "def~" + REPR 127 + REPR 10 + REPR 150 + REPR 152 + "!";
print( ( "<<" + t + ">> - without control characters:             <<" + strip characters( t, FALSE ) + ">>", newline ) );
print( ( "<<" + t + ">> - without control or extended characters: <<" + strip characters( t, TRUE  ) + ">>", newline ) )


procedure main()
    unp := &cset[1+:32]++' \t'++&cset[127:0]   # all 'unprintable' chars
    s := " Hello, people of earth!  	"
    write("Original:      '",s,"'")
    write("leading trim:  '",reverse(trim(reverse(s),unp)),"'")
    write("trailing trim: '",trim(s,unp),"'")
    write("full trim:     '",reverse(trim(reverse(trim(s,unp)),unp)),"'")
end


   require 'strings'                      NB. the strings library is automatically loaded in versions from J7 on
   quote dlb '  String with spaces   '    NB. delete leading blanks
'String with spaces   '
   quote dtb '  String with spaces   '    NB. delete trailing blanks
'  String with spaces'
   quote dltb '  String with spaces   '   NB. delete leading and trailing blanks
'String with spaces'


public class Trims{
    public static String ltrim(String s) {
        int i = 0;
        while (i < s.length() && Character.isWhitespace(s.charAt(i))) {
            i++;
        }
        return s.substring(i);
    }

    public static String rtrim(String s) {
        int i = s.length() - 1;
        while (i > 0 && Character.isWhitespace(s.charAt(i))) {
            i--;
        }
        return s.substring(0, i + 1);
    }

    public static String trim(String s) {
    	return rtrim(ltrim(s));
    }

    public static void main(String[] args) {
        String s = " \t \r \n String with spaces \u2009 \t  \r  \n  ";
        System.out.printf("[%s]\n", ltrim(s));
        System.out.printf("[%s]\n", rtrim(s));
        System.out.printf("[%s]\n", trim(s));
    }
}


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


package main

import (
    "fmt"
    "strings"
)

// idiomatic to name a function newX that allocates an object, initializes it,
// and returns it ready to use.  the object in this case is a closure.
func newStripper(start, end string) func(string) string {
    // default to c-style block comments
    if start == "" || end == "" {
        start, end = "/*", "*/"
    }
    // closes on variables start, end.
    return func(source string) string {
        for {
            cs := strings.Index(source, start)
            if cs < 0 {
                break
            }
            ce := strings.Index(source[cs+2:], end)
            if ce < 0 {
                break
            }
            source = source[:cs] + source[cs+ce+4:]
        }
        return source
    }
}

func main() {
    // idiomatic is that zero values indicate to use meaningful defaults
    stripC := newStripper("", "")

    // strip function now defined and can be called any number of times
    // without respecifying delimiters
    fmt.Println(stripC(`  /**
   * Some comments
   * longer comments here that we can parse.
   *
   * Rahoo
   */
   function subroutine() {
    a = /* inline comment */ b + c ;
   }
   /*/ <-- tricky comments */

   /**
    * Another comment.
    */
    function something() {
    }`))
}


str: {string of ☺☻♥♦⌂, may include control characters and other    ♫☼§►↔◄░▒▓█┌┴┐±÷²¬└┬┘ilk.}

print "with extended characters"
print join select split str 'x ->
    not? in? to :integer to :char x (0..31)++127

print "without extended characters"
print join select split str 'x ->
    and? ascii? x
         not? in? to :integer to :char x (0..31)++127


Stripped(x){
	Loop Parse, x
		if Asc(A_LoopField) > 31 and Asc(A_LoopField) < 128
			r .= A_LoopField
	return r
}
MsgBox % stripped("`ba" Chr(00) "b`n`rc`fd" Chr(0xc3))


# syntax: GAWK -f STRIP_CONTROL_CODES_AND_EXTENDED_CHARACTERS.AWK
BEGIN {
    s = "ab\xA2\x09z" # a b cent tab z
    printf("original string: %s (length %d)\n",s,length(s))
    gsub(/[\x00-\x1F\x7F]/,"",s); printf("control characters stripped: %s (length %d)\n",s,length(s))
    gsub(/[\x80-\xFF]/,"",s); printf("control and extended stripped: %s (length %d)\n",s,length(s))
    exit(0)
}


{
    let s = " \t String with spaces  \t  ";
    // a future version of ECMAScript will have trimStart().  Some current
    // implementations have trimLeft().
    console.log("original: '" + s + "'");
    console.log("trimmed left: '" + s.replace(/^\s+/,'') + "'");
    // a future version of ECMAScript will have trimEnd().  Some current
    // implementations have trimRight().
    console.log("trimmed right: '" + s.replace(/\s+$/,'') + "'");
    console.log("trimmed both: '" + s.trim() + "'");
 }


def lstrip: sub( "^[\\s\\p{Cc}]+"; "" );

def rstrip: sub( "[\\s\\p{Cc}]+$"; "" );

def strip: lstrip | rstrip;


#!/usr/bin/env jsish
/* Strip whitespace from string, in Jsi */
var str = ' \n \t String with whitespace \t \n ';
;'Original';
;str;

;'Default trim characters are space, tab, newline, carriage return';
;'trimLeft, remove leading characters';
;str.trimLeft();

;'trimRight, remove trailing characters';
;str.trimRight();

;'trim, removes leading and trailing';
;str.trim();

/*
=!EXPECTSTART!=
'Original'
str ==>
     String with whitespace

'Default trim characters are space, tab, newline, carriage return'
'trimLeft, remove leading characters'
str.trimLeft() ==> String with whitespace

'trimRight, remove trailing characters'
str.trimRight() ==>
     String with whitespace
'trim, removes leading and trailing'
str.trim() ==> String with whitespace
=!EXPECTEND!=
*/


def code = """
  /**
   * Some comments
   * longer comments here that we can parse.
   *
   * Rahoo
   */
   function subroutine() {
    a = /* inline comment */ b + c ;
   }
   /*/ <-- tricky comments */

   /**
    * Another comment.
    */
    function something() {
    }
"""

println ((code =~ "(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)").replaceAll(''))


test = "This {- is not the beginning of a block comment" -- Do your homework properly -}


procedure main()
   every (unstripped := "") ||:= !&input || "\n"   # Load file as one string
   write(stripBlockComment(unstripped,"/*","*/"))
end

procedure stripBlockComment(s1,s2,s3)  #: strip comments between s2-s3 from s1
   result := ""
   s1 ? {
      while result ||:= tab(find(s2)) do {
         move(*s2)
         tab(find(s3)|0)   # or end of string
         move(*s3)
         }
      return result || tab(0)
      }
end


DECLARE FUNCTION strip$ (what AS STRING)
DECLARE FUNCTION strip2$ (what AS STRING)

DIM x AS STRING, y AS STRING, z AS STRING

'   tab                c+cedilla           eof
x = CHR$(9) + "Fran" + CHR$(135) + "ais" + CHR$(26)
y = strip(x)
z = strip2(x)

PRINT "x:"; x
PRINT "y:"; y
PRINT "z:"; z

FUNCTION strip$ (what AS STRING)
    DIM outP AS STRING, L0 AS INTEGER, tmp AS STRING
    FOR L0 = 1 TO LEN(what)
        tmp = MID$(what, L0, 1)
        SELECT CASE ASC(tmp)
            CASE 32 TO 126
                outP = outP + tmp
        END SELECT
    NEXT
    strip$ = outP
END FUNCTION

FUNCTION strip2$ (what AS STRING)
    DIM outP AS STRING, L1 AS INTEGER, tmp AS STRING
    FOR L1 = 1 TO LEN(what)
        tmp = MID$(what, L1, 1)
        SELECT CASE ASC(tmp)
                'normal     accented    various     greek, math, etc.
            CASE 32 TO 126, 128 TO 168, 171 TO 175, 224 TO 253
                outP = outP + tmp
        END SELECT
    NEXT
    strip2$ = outP
END FUNCTION


      test$ = CHR$(9) + "Fran" + CHR$(231) + "ais." + CHR$(127)
      PRINT "Original ISO-8859-1 string: " test$ " (length " ; LEN(test$) ")"
      test$ = FNstripcontrol(test$)
      PRINT "Control characters stripped: " test$ " (length " ; LEN(test$) ")"
      test$ = FNstripextended(test$)
      PRINT "Control & extended stripped: " test$ " (length " ; LEN(test$) ")"
      END

      DEF FNstripcontrol(A$) : REM CHR$(127) is a 'control' code
      LOCAL I%
      WHILE I%<LEN(A$)
        I% += 1
        IF ASCMID$(A$,I%)<32 OR ASCMID$(A$,I%)=127 THEN
          A$ = LEFT$(A$,I%-1) + MID$(A$,I%+1)
        ENDIF
      ENDWHILE
      = A$

      DEF FNstripextended(A$)
      LOCAL I%
      WHILE I%<LEN(A$)
        I% += 1
        IF ASCMID$(A$,I%)>127 THEN
          A$ = LEFT$(A$,I%-1) + MID$(A$,I%+1)
        ENDIF
      ENDWHILE
      = A$


julia> s = " \t \r \n String with spaces  \t  \r  \n  "
" \t \r \n String with spaces  \t  \r  \n  "

julia> lstrip(s)
"String with spaces  \t  \r  \n  "

julia> rstrip(s)
" \t \r \n String with spaces"

julia> strip(s)
"String with spaces"


fun main(args: Array<String>) {
    val s = "  \tRosetta Code \r \u2009 \n"
    println("Untrimmed       => [$s]")
    println("Left Trimmed    => [${s.trimStart()}]")
    println("Right Trimmed   => [${s.trimEnd()}]")
    println("Fully Trimmed   => [${s.trim()}]")
}


#!/bin/ksh

# Strip whitespace from a string/Top and tail

#	# Variables:
#
str=${1:-"	This is a test.   "}

#	# Functions:
#

#	# Function _striphead(str) - Return str with leading while space stripped
#
function _striphead {
	typeset _str ; _str="$1"

	echo "${_str##*(\s)}"
}

#	# Function _striptail(str) - Return str with trailing while space stripped
#
function _striptail {
	typeset _str ; _str="$1"

	while [[ ${_str} != ${_str%+(\s)} ]]; do
		_str=${_str%+(\s)}
	done
	echo "${_str}"
}

 ######
# main #
 ######

printf ">%s<  (Unstripped %d chars)\n" "${str}" ${#str}
sstr=$(_striphead "${str}")
printf ">%s<  (Strip leading (%d chars))\n" "${sstr}" $(( ${#str}-${#sstr} ))
sstr=$(_striptail "${str}")
printf ">%s<  (Strip trailing (%d chars))\n" "${sstr}" $(( ${#str}-${#sstr} ))
sstr=$(_striphead "$(_striptail "${str}")")
printf ">%s<  (Strip both (%d chars))\n" "${sstr}" $(( ${#str}-${#sstr} ))


initial string : {def string ___String with "_" displaying space_____}
          -> string ___String with "_" displaying space_____

trimLeft       :  {S.replace ^_+ by in {string}}
          -> String with "_" displaying space_____

trimRight      : {S.replace _+$ by in {string}}
          -> ___String with "_" displaying space

trimBoth       :  {S.replace _+$ by in {S.replace ^_+ by in {string}}}
          -> String with "_" displaying space


F remove_comments(line, sep)
   V? p = line.find(sep)
   I p != N
      R line[0.<p].rtrim(‘ ’)
   R line

print(remove_comments(‘apples ; pears # and bananas’, (‘;’, ‘#’)))
print(remove_comments(‘apples ; pears # and bananas’, ‘#’))
print(remove_comments(‘apples ; pears # and bananas’, ‘!’))


import java.io.*;

public class StripBlockComments{
    public static String readFile(String filename) {
	BufferedReader reader = new BufferedReader(new FileReader(filename));
	try {
	    StringBuilder fileContents = new StringBuilder();
	    char[] buffer = new char[4096];
	    while (reader.read(buffer, 0, 4096) > 0) {
		fileContents.append(buffer);
	    }
	    return fileContents.toString();
	} finally {
	    reader.close();
	}
    }

    public static String stripComments(String beginToken, String endToken,
				       String input) {
	StringBuilder output = new StringBuilder();
	while (true) {
	    int begin = input.indexOf(beginToken);
	    int end = input.indexOf(endToken, begin+beginToken.length());
	    if (begin == -1 || end == -1) {
		output.append(input);
		return output.toString();
	    }
	    output.append(input.substring(0, begin));
	    input = input.substring(end + endToken.length());
	}
    }

    public static void main(String[] args) {
	if (args.length < 3) {
	    System.out.println("Usage: BeginToken EndToken FileToProcess");
	    System.exit(1);
	}

	String begin = args[0];
	String end = args[1];
	String input = args[2];

	try {
	    System.out.println(stripComments(begin, end, readFile(input)));
	} catch (Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
    }
}


(  "string of ☺☻♥♦⌂, may include control
characters and other ilk.\L\D§►↔◄
Rødgrød med fløde"
  : ?string1
  : ?string2
& :?newString
&   whl
  ' ( @(!string1:?clean (%@:<" ") ?string1)
    & !newString !clean:?newString
    )
& !newString !string1:?newString
& out$(str$("Control characters stripped:
" str$!newString))
& :?newString
&   whl
  ' ( @(!string2:?clean (%@:(<" "|>"~")) ?string2)
    & !newString !clean:?newString
    )
& !newString !string2:?newString
&   out
  $ ( str
    $ ( "
Control characters and extended characters stripped:
"
        str$!newString
      )
    )
& );


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAXBUF 256  /* limit */
#define STR_SZ 100  /* string size */

/* function prototypes */
int ascii (const unsigned char c);

int ascii_ext (const unsigned char c);

unsigned char* strip(unsigned char* str, const size_t n, int ext );

/* check a character
   return 1 for true
          0 for false
*/
int ascii (const unsigned char c)
{
  unsigned char min = 32;   /* <space> */
  unsigned char max = 126;  /* ~ tilde */

  if ( c>=min && c<=max ) return 1;

  return 0;
}

/* check if extended character
   return 1 for true
          0 for false
*/
int ascii_ext (const unsigned char c)
{
  unsigned char min_ext = 128;
  unsigned char max_ext = 255;

  if ( c>=min_ext && c<=max_ext )
       return 1;

  return 0;
}

/* fill buffer with only ASCII valid characters
   then rewrite string from buffer
   limit to n < MAX chars
*/

unsigned char* strip( unsigned char* str, const size_t n, int ext)
{

  unsigned char buffer[MAXBUF] = {'\0'};

  size_t i = 0;  // source index
  size_t j = 0;  // dest   index

  size_t max = (n<MAXBUF)? n : MAXBUF -1;  // limit size

  while (i < max )
    {
      if ( (ext && ascii_ext(str[i]) ) ||  (ascii(str[i]) ) )    // check
	{
	  buffer[j++] = str[i]; // assign
	}
      i++;
    }

  memset(str, '\0', max); // wipe string

  i = 0;               // reset count

  while( i < j)
    {
      str[i] = buffer[i]; // copy back
      i++;
    }

  str[j] = '\0';  // terminate properly

  return str;
}

/* try it out */
int main( int argc, char** argv)
{
  enum {ASCII=0, EXT=1}; /* enumeration makes easier reading */

  unsigned int seed = 134529;  // RNG seed value

  /* variables and storage */
  unsigned char badstring[STR_SZ] = {'\0'};
  unsigned char bs_2[STR_SZ]      = {'\0'};

  unsigned char* goodstring = NULL;
  unsigned char* goodstring_ext = NULL;

  size_t i = 0;

  srand(seed); /* seed RNG */

  fprintf(stdout, "Original:\t" );

  /* generate a random string */
  for (i = 0; i < STR_SZ; i++)
    {
      badstring[i] = (unsigned char) ( rand () & (unsigned char)0xFF );
      fprintf(stdout, "%c", badstring[i] );
    }
  fprintf(stdout, "\n");

   memcpy(bs_2, badstring, STR_SZ * sizeof(unsigned char) ); /* copy string */

   goodstring_ext = strip( badstring, STR_SZ, EXT); /* remove non-extended and non-ascii */

   fprintf(stdout, "\nEXT:\t%s\n" , goodstring_ext );

   goodstring = strip( bs_2, STR_SZ, ASCII); /* remove all non-ascii */

   fprintf(stdout, "\nASCII:\t%s\n" , goodstring );

return 0;
}


// String with leading whitespace removed
'>' + ('  \t   Hello')->trim& + '<'

// String with trailing whitespace removed
'>' + ('Hello  \t   ')->trim& + '<'

// String with both leading and trailing whitespace removed
'>' + ('   \t  Hello  \t   ')->trim& + '<'


a$="   This is a test   "

'LB TRIM$ removes characters with codes 0..31 as well as a space(code 32)
'So these versions of ltrim rtrim remove them too
'a$="   "+chr$(31)+"This is a test"+chr$(31)+"   "

print "Source line"
print ">";a$;"<"
print "Strip left"
print ">";ltrim$(a$);"<"
print "Strip right"
print ">";rtrim$(a$);"<"
print "Strip both"
print ">";trim$(a$);"<"

end

function ltrim$(a$)
    c$=trim$(a$+".")
    ltrim$ = mid$(c$, 1, len(c$)-1)
end function

function rtrim$(a$)
    c$=trim$("."+a$)
    rtrim$ = mid$(c$, 2)
end function


:- object(whitespace).

    :- public(trim/4).

    trim(String, TrimLeft, TrimRight, TrimBoth) :-
        trim_left(String, TrimLeft),
        trim_right(String, TrimRight),
        trim_right(TrimLeft, TrimBoth).

    trim_left(String, TrimLeft) :-
        atom_codes(String, Codes),
        trim(Codes, TrimCodes),
        atom_codes(TrimLeft, TrimCodes).

    trim_right(String, TrimRight) :-
        atom_codes(String, Codes),
        list::reverse(Codes, ReverseCodes),
        trim(ReverseCodes, ReverseTrimCodes),
        list::reverse(ReverseTrimCodes, TrimCodes),
        atom_codes(TrimRight, TrimCodes).

    trim([], []).
    trim([InCode| InCodes], OutCodes) :-
        (   InCode =< 32 ->
            trim(InCodes, OutCodes)
        ;   OutCodes = [InCode| InCodes]
        ).

:- end_object.


StripComments:
	;prints a string but stops at the comment character
	;INPUT: D7 = comment character(s) of choice
        ;A0 = source address of string
	;up to four can be used, each takes up a different 8 bits of the register
	;to omit an argument, leave its bits as zero.
.loop:
	MOVE.B (A0)+,D0
	CMP.B #0,D0			;check for null terminator
	beq .done

	CMP.B D7,D0                     ;check the first comment char
	beq .done
	ROR.L #8,D7

	CMP.B D7,D0                     ;check the second comment char
	beq .done
	ROR.L #8,D7

	CMP.B D7,D0                      ;check the third comment char
	beq .done
	ROR.L #8,D7

	CMP.B D7,D0                      ;check the fourth comment char
	beq .done
	ROR.L #8,D7

	CMP.B #' ',D0
	BNE dontCheckNext
		MOVE.B (A0),D1           ;look ahead one character, if that character is a comment char or null terminator, stop here

		CMP.B #0,D1
		beq .done

		CMP.B D7,D1
		beq .done
		ROR.L #8,D7

		CMP.B D7,D1
		beq .done
		ROR.L #8,D7

		CMP.B D7,D1
		beq .done
		ROR.L #8,D7

		CMP.B D7,D1
		beq .done
		ROR.L #8,D7

dontCheckNext:
	jsr PrintChar
	bra .loop

.done:
	rts

TestString:
	dc.b "apples ; pears # and bananas",0


PROC Strip(CHAR ARRAY text,chars,result)
  BYTE i,j,pos,found

  pos=text(0)
  FOR i=1 TO text(0)
  DO
    found=0
    FOR j=1 TO chars(0)
    DO
      IF text(i)=chars(j) THEN
        found=1 EXIT
      FI
    OD
    IF found THEN
      pos=i-1 EXIT
    FI
  OD
  WHILE pos>0 AND text(pos)='
  DO
    pos==-1
  OD
  SCopyS(result,text,1,pos)
RETURN

PROC Test(CHAR ARRAY text,chars)
  CHAR ARRAY result(255)

  Strip(text,chars,result)
  PrintF("""%S"", ""%S"" -> ""%S""%E%E",text,chars,result)
RETURN

PROC Main()
  Test("apples, pears # and bananas","#;")
  Test("apples, pears ; and bananas","#;")
  Test("qwerty # asdfg ; zxcvb","#")
  Test("qwerty # asdfg ; zxcvb",";")
  Test("   ;this is a comment","#;")
  Test("#this is a comment","#;")
  Test("       ",";")
  Test("","#")
RETURN


with Ada.Text_IO;
procedure Program is
   Comment_Characters : String := "#;";
begin
   loop
      declare
	 Line : String := Ada.Text_IO.Get_Line;
      begin
	 exit when Line'Length = 0;
	 Outer_Loop : for I in Line'Range loop
	    for J in Comment_Characters'Range loop
	       if Comment_Characters(J) = Line(I) then
		  Ada.Text_IO.Put_Line(Line(Line'First .. I - 1));
		  exit Outer_Loop;
	       end if;
	    end loop;
	 end loop Outer_Loop;
      end;
   end loop;
end Program;


function _stripcomments(txt::AbstractString, dlm::Tuple{String,String})
    "Strips first nest of block comments"

    dlml, dlmr = dlm
    indx = searchindex(txt, dlml)
    if indx > 0
        out = IOBuffer()
        write(out, txt[1:indx-1])
        txt = txt[indx+length(dlml):end]
        txt = _stripcomments(txt, dlm)
        indx = searchindex(txt, dlmr)
        @assert(indx > 0, "cannot find a closer delimiter \"$dlmr\" in $txt")
        write(out, txt[indx+length(dlmr):end])
    else
        out = txt
    end
    return String(out)
end

function stripcomments(txt::AbstractString, dlm::Tuple{String,String}=("/*", "*/"))
    "Strips nests of block comments"

    dlml, dlmr = dlm
    while contains(txt, dlml)
        txt = _stripcomments(txt, dlm)
    end

    return txt
end

function main()
    println("\nNON-NESTED BLOCK COMMENT EXAMPLE:")
    smpl = """
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*/
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */

/**
* Another comment.
*/
function something() {
}
"""
    println(stripcomments(smpl))

    println("\nNESTED BLOCK COMMENT EXAMPLE:")
    smpl = """
/**
* Some comments
* longer comments here that we can parse.
*
* Rahoo
*//*
function subroutine() {
a = /* inline comment */ b + c ;
}
/*/ <-- tricky comments */
*/
/**
* Another comment.
*/
function something() {
}
"""
    println(stripcomments(smpl))
end

main()


// version 1.1.4-3

val sample = """
/**
   * Some comments
   * longer comments here that we can parse.
   *
   * Rahoo
   */
   function subroutine() {
    a = /* inline comment */ b + c ;
   }
   /*/ <-- tricky comments */

   /**
    * Another comment.
    */
    function something() {
    }
"""

val sample2 = """
``{
   ` Some comments
   ` longer comments here that we can parse.
   `
   ` Rahoo
   ``}
   function subroutine2() {
    d = ``{ inline comment ``} e + f ;
   }
   ``{ / <-- tricky comments ``}

   ``{
    ` Another comment.
    ``}
    function something2() {
    }
"""

fun stripBlockComments(text: String, del1: String = "/*", del2: String = "*/"): String {
    val d1 = Regex.escape(del1)
    val d2 = Regex.escape(del2)
    val r = Regex("""(?s)$d1.*?$d2""")
    return text.replace(r, "")
}

fun main(args: Array<String>) {
    println(stripBlockComments(sample))
    println(stripBlockComments(sample2, "``{", "``}"))
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RosettaCode
{
    class Program
    {
        static void Main(string[] args)
        {
            string test = "string of ☺☻♥♦⌂, may include control characters and other ilk.♫☼§►↔◄";
            Console.WriteLine("Original: {0}", test);
            Console.WriteLine("Stripped of control codes: {0}", StripControlChars(test));
            Console.WriteLine("Stripped of extended: {0}", StripExtended(test));
        }

        static string StripControlChars(string arg)
        {
            char[] arrForm = arg.ToCharArray();
            StringBuilder buffer = new StringBuilder(arg.Length);//This many chars at most

            foreach(char ch in arrForm)
                if (!Char.IsControl(ch)) buffer.Append(ch);//Only add to buffer if not a control char

            return buffer.ToString();
        }

        static string StripExtended(string arg)
        {
            StringBuilder buffer = new StringBuilder(arg.Length); //Max length
            foreach(char ch in arg)
            {
                UInt16 num = Convert.ToUInt16(ch);//In .NET, chars are UTF-16
                //The basic characters have the same code points as ASCII, and the extended characters are bigger
                if((num >= 32u) && (num <= 126u)) buffer.Append(ch);
            }
            return buffer.ToString();
        }
    }
}


#include <string>
#include <iostream>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/casts.hpp>
#include <ctime>
#include <cstdlib>
using namespace boost::lambda ;

struct MyRandomizer {
   char operator( )( ) {
      return static_cast<char>( rand( ) % 256 ) ;
   }
} ;

std::string deleteControls ( std::string startstring ) {
   std::string noControls( "                                        " ) ;//creating space for
   //the standard algorithm remove_copy_if
   std::remove_copy_if( startstring.begin( ) , startstring.end( ) , noControls.begin( ) ,
	 ll_static_cast<int>( _1 ) < 32 && ll_static_cast<int>( _1 ) == 127 ) ;
   return noControls ;
}

std::string deleteExtended( std::string startstring ) {
   std::string noExtended ( "                                        " ) ;//same as above
   std::remove_copy_if( startstring.begin( ) , startstring.end( ) , noExtended.begin( ) ,
	 ll_static_cast<int>( _1 ) > 127 || ll_static_cast<int>( _1 ) < 32 ) ;
   return noExtended ;
}

int main( ) {
   std::string my_extended_string ;
   for ( int i = 0 ; i < 40 ; i++ ) //we want the extended string to be 40 characters long
      my_extended_string.append( " " ) ;
   srand( time( 0 ) ) ;
   std::generate_n( my_extended_string.begin( ) , 40 , MyRandomizer( ) ) ;
   std::string no_controls( deleteControls( my_extended_string ) ) ;
   std::string no_extended ( deleteExtended( my_extended_string ) ) ;
   std::cout << "string with all characters: " << my_extended_string << std::endl ;
   std::cout << "string without control characters: " << no_controls << std::endl ;
   std::cout << "string without extended characters: " << no_extended << std::endl ;
   return 0 ;
}


str = " \t \r \n String with spaces  \t  \r  \n  "

print( string.format( "Leading whitespace removed: %s", str:match( "^%s*(.+)" ) ) )
print( string.format( "Trailing whitespace removed: %s", str:match( "(.-)%s*$" ) ) )
print( string.format( "Leading and trailing whitespace removed: %s", str:match( "^%s*(.-)%s*$" ) ) )


Module CheckIt {
	filter$=chr$(0)
	for i=1 to 31:filter$+=chr$(i):next
	a$=chr$(9)+"    There are unwanted blanks here!    "+chr$(9)
	a$=filter$(a$,filter$) ' exclude non printable characters

	\\ string encoded as UTF16LE
	Print Len(a$)=39
	Print(ltrim$(a$))
	Print(rtrim$(a$))
	Print(trim$(a$))
	\\ string encoded as ANSI base to Locale
	oldlocale=Locale
	Locale 1033
	a$=str$(a$)
	Print Len(a$)=19.5  ' unit for length is a word (2 bytes), so 19.5 means  19.5*2 bytes= 39 bytes
	PrintAnsi(ltrim$(a$ as byte))
	PrintAnsi(rtrim$(a$ as byte))
	PrintAnsi(trim$(a$ as byte))
	Locale oldlocale
	Sub Print(a$)
		Print "*"+a$+"*"
	End Sub
	Sub PrintAnsi(a$)
		Print "*"+chr$(a$)+"*"
	End Sub
}
Checkit


str := " \t \r \n String with spaces  \t  \r  \n  ";

with(StringTools):

TrimLeft(str);
TrimRight(str);
Trim(str);


strip_comments(data b)
{
    b.size(b.look(0, ";#")).bf_drop(" \t").bb_drop(" \t");
}

main(void)
{
    for (, text n in list("apples, pears # and bananas", "apples, pears ; and bananas")) {
        o_(strip_comments(n), "\n");
    }

    0;
}


#!/usr/local/bin/a68g --script #

PROC trim comment = (STRING line, CHAR marker)STRING:(
  INT index := UPB line+1;
  char in string(marker, index, line);
  FOR i FROM index-1 BY -1 TO LWB line
  WHILE line[i]=" " DO index := i OD;
  line[:index-1]
);

CHAR q = """";

print((
  q, trim comment("apples, pears # and bananas", "#"), q, new line,
  q, trim comment("apples, pears ; and bananas", ";"), q, new line,
  q, trim comment("apples, pears and bananas  ", ";"), q, new line,
  q, trim comment("    ", ";"), q, new line, # blank string #
  q, trim comment("", ";"), q, new line  # empty string #
))

CO Alternatively Algol68g has available "grep"
;STRING re marker := " *#", line := "apples, pears # and bananas";
  INT index := UPB line;
  grep in string(re marker, line, index, NIL);
  print((q, line[:index-1], q, new line))
END CO


begin
    % determines the non-comment portion of the string s, startPos and endPos are   %
    % returned set to the beginning and ending character positions (indexed from 0) %
    % of the non-comment text in s. If there is no non-comment text in s, startPos  %
    % will be greater than endPos                                                   %
    % note that in Algol W, strings can be at most 256 characters long              %
    procedure stripComments ( string(256) value s; integer result startPos, endPos ) ;
    begin
        integer MAX_LENGTH;
        MAX_LENGTH := 256;
        startPos   :=  0;
        endPos     := -1;
        % find the first non-blank character in s %
        while startPos < MAX_LENGTH and s( startPos // 1 ) = " " do startPos := startPos + 1;
        if startPos < MAX_LENGTH then begin
            % have a non-blank character in the string %
            if s( startPos // 1 ) not = "#" and s( startPos // 1 ) not = ";" then begin
                % the non-blank character is not a comment delimiter %
                integer cPos;
                cPos := endPos := startPos;
                while cPos < MAX_LENGTH and s( cPos // 1 ) not = "#" and s( cPos // 1 ) not = ";" do begin
                    if s( cPos // 1 ) not = " " then endPos := cPos;
                    cPos := cPos + 1
                end while_not_a_comment
            end if_not_a_comment
        end if_startPos_lt_MAX_LENGTH
    end stripComments ;
    % tests the stripComments procedure                                             %
    procedure testStripComments( string(256) value s ) ;
    begin
        integer startPos, endPos;
        stripComments( s, startPos, endPos );
        write( """" );
        for cPos := startPos until endPos do writeon( s( cPos // 1 ) );
        writeon( """" )
    end testStripComments ;
    begin % test cases - should all print "apples, pears"                           %
        testStripComments( "apples, pears # and bananas" );
        testStripComments( "apples, pears ; and bananas" );
        testStripComments( "apples, pears "              );
        testStripComments( "              apples, pears" )
    end
end.


#!/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}"


global CRLF$
CRLF$ =chr$( 13) +chr$( 10)

sample$ ="  /**"+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$

startDelim$  ="/*"
finishDelim$ ="*/"

print "________________________________"
print sample$
print "________________________________"
print blockStripped$( sample$, startDelim$, finishDelim$)
print "________________________________"

end

function blockStripped$( in$, s$, f$)
    for i =1 to len( in$) -len( s$)
        if mid$( in$, i, len( s$)) =s$ then
            i =i +len( s$)
            do
                if mid$( in$, i, 2) =CRLF$ then blockStripped$ =blockStripped$ +CRLF$
                i =i +1
            loop until ( mid$( in$, i, len( f$)) =f$) or ( i =len( in$) -len( f$))
            i =i +len( f$) -1
        else
            blockStripped$ =blockStripped$ +mid$( in$, i, 1)
        end if
    next i
end function


; generate our test string of characters with control and extended characters
(def range-of-chars (apply str (map char (range 256))))

; filter out the control characters:
(apply str (filter #(not (Character/isISOControl %)) range-of-chars))

; filter to return String of characters that are between 32 - 126:
(apply str (filter #(<= 32 (int %) 126) range-of-chars))


(defun control-char-p (ch)
  (or (< (char-code ch) 32)
      (= (char-code ch) 127)))

(defun extended-char-p (ch)
  (> (char-code ch) 127))

(defun strip-special-chars (string &key strip-extended)
  (let ((needs-removing-p (if strip-extended
                              (lambda (ch)
                                (or (control-char-p ch)
                                    (extended-char-p ch)))
                              #'control-char-p)))
    (remove-if needs-removing-p string)))


import std.traits;

S stripChars(S)(S s, bool function(dchar) pure nothrow mustStrip)
        pure nothrow if (isSomeString!S) {
    S result;
    foreach (c; s) {
        if (!mustStrip(c))
            result ~= c;
    }
    return result;
}

void main() {
    import std.stdio, std.uni;
    auto s = "\u0000\u000A abc\u00E9def\u007F";
    writeln(s.stripChars( &isControl ));
    writeln(s.stripChars( c => isControl(c) || c == '\u007F' ));
    writeln(s.stripChars( c => isControl(c) || c >= '\u007F' ));
}


StringTrim[" \n\t    string with spaces   \n   \t   "]


% remove trailing whitespaces
    str = str(1:find(~isspace(str),1,'last'));
% remove leading whitespaces
    str = str(find(~isspace(str),1):end);

% removes leading and trailing whitespaces, vectorized version
    f = ~isspace(str);
    str = str(find(f,1,'first'):find(f,1,'last');

% a built-in function, removes leading and trailing whitespaces
    str = strtrim(str);


:- module top_and_tail.
:- interface.

:- import_module io.
:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module list, string.

main(!IO) :-
   TestPhrase = "\t\r\n String with spaces \t\r\n ",
   io.format("leading ws removed: %s\n", [s(lstrip(TestPhrase))], !IO),
   io.format("trailing ws removed: %s\n", [s(rstrip(TestPhrase))], !IO),
   io.format("both removed: %s\b", [s(strip(TestPhrase))], !IO).


10 LET C$ = ";#"
20 S$(1)="APPLES, PEARS # AND BANANAS"
30 S$(2)="APPLES, PEARS ; AND BANANAS"
40 FOR Q = 1 TO 2
50     LET S$ = S$(Q)
60     GOSUB 100"STRIP COMMENTS
70     PRINT S$
80 NEXT Q
90 END

100 IF S$ = "" THEN RETURN
110 FOR I = 1 TO LEN(S$)
120     LET A$ = MID$(S$, I, 1)
130     FOR J = 1 TO LEN(C$)
140         LET F$ = MID$(C$, J, 1)
150         IF A$ <> F$ THEN NEXT J
160     IF A$ = F$ THEN 200
170 NEXT I
200 LET I = I - 1
210 GOSUB 260"STRIP
220 IF S$ = "" THEN RETURN
230 FOR I = I TO 0 STEP -1
240     LET A$ = MID$(S$, I, 1)
250     IF A$ = " " THEN NEXT I
260 LET S$ = MID$(S$, 1, I)
270 RETURN


stripComments: function [str][
    strip replace str {/[#;].+/} ""
]

loop ["apples, pears # and bananas", "apples, pears ; and bananas"] 'str [
    print [str "->" stripComments str]
]


Delims := "#;"
str := "apples, pears # and bananas"
str2:= "apples, pears, `; and bananas" ; needed to escape the ; since that is AHK's comment marker
msgbox % StripComments(Str,Delims)
msgbox % StripComments(Str2,Delims)
; The % forces expression mode.

StripComments(String1,Delims){
    Loop, parse, delims
    {
        If Instr(String1,A_LoopField)
            EndPosition := InStr(String1,A_LoopField) - 1
        Else
            EndPosition := StrLen(String1)
        StringLeft, String1, String1, EndPosition
    }
    return String1
}


Dim $Line1 = "apples, pears # and bananas"
Dim $Line2 = "apples, pears ; and bananas"

_StripAtMarker($Line1)
_StripAtMarker($Line2)

Func _StripAtMarker($_Line, $sMarker='# ;')
	Local $aMarker = StringSplit($sMarker, ' ')
	Local $iPos
	For $i = 1 To $aMarker[0]
		$iPos = StringInStr($_Line, $aMarker[$i])
		If $iPos Then
			ConsoleWrite($_Line & @CRLF)
			ConsoleWrite( StringStripWS( StringLeft($_Line, $iPos -1), 2) & @CRLF)
		EndIf
	Next
EndFunc  ;==>_StripAtMarker


filename = "Text1.txt"

fp = io.open( filename, "r" )
str = fp:read( "*all" )
fp:close()

stripped = string.gsub( str, "/%*.-%*/", "" )
print( stripped )


StringReplace[a,"/*"~~Shortest[___]~~"*/" -> ""]

->
   function subroutine() {
    a =  b + c ;
   }

    function something() {
    }


function str = stripblockcomment(str,startmarker,endmarker)
   while(1)
      ix1 = strfind(str, startmarker);
      if isempty(ix1) return; end;
      ix2 = strfind(str(ix1+length(startmarker):end),endmarker);
      if isempty(ix2)
         str = str(1:ix1(1)-1);
         return;
      else
         str = [str(1:ix1(1)-1),str(ix1(1)+ix2(1)+length(endmarker)+1:end)];
      end;
   end;
end;


import strutils

proc commentStripper(txt: string; delim: tuple[l, r: string] = ("/*", "*/")): string =
  let i = txt.find(delim.l)
  if i < 0: 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
  result &= tmp[j+delim.r.len .. tmp.high]

echo "NON-NESTED BLOCK COMMENT EXAMPLE:"
echo commentStripper("""/**
   * Some comments
   * longer comments here that we can parse.
   *
   * Rahoo
   */
   function subroutine() {
    a = /* inline comment */ b + c ;
   }
   /*/ <-- tricky comments */

   /**
    * Another comment.
    */
    function something() {
    }""")

echo "\nNESTED BLOCK COMMENT EXAMPLE:"
echo commentStripper("""  /**
   * Some comments
   * longer comments here that we can parse.
   *
   * Rahoo
   *//*
   function subroutine() {
    a = /* inline comment */ b + c ;
   }
   /*/ <-- tricky comments */
   */
   /**
    * Another comment.
    */
    function something() {
    }""")


-module( strip_control_codes ).

-export( [is_not_control_code/1, is_not_control_code_nor_extended_character/1, task/0] ).

is_not_control_code( C ) when C > 127 -> true;
is_not_control_code( C ) when C < 32; C =:= 127 -> false;
is_not_control_code( _C ) -> true.

is_not_control_code_nor_extended_character( C ) when C > 127 -> false;
is_not_control_code_nor_extended_character( C )	-> is_not_control_code( C ).

task() ->
    String = lists:seq( 0, 255 ),
    io:fwrite( "String (~p characters): ~s~n", [erlang:length(String), String] ),
    String_without_cc = lists:filter( fun is_not_control_code/1, String ),
    io:fwrite( "String without control codes (~p characters): ~s~n", [erlang:length(String_without_cc), String_without_cc] ),
    String_without_cc_nor_ec = lists:filter( fun is_not_control_code_nor_extended_character/1, String ),
    io:fwrite( "String without control codes nor extended characters (~p characters): ~s~n", [erlang:length(String_without_cc_nor_ec), String_without_cc_nor_ec] ).


open System

let stripControl (arg:string) =
    String(Array.filter (fun x -> not (Char.IsControl(x))) (arg.ToCharArray()))
//end stripControl

let stripExtended (arg:string) =
    let numArr = Array.map (fun (x:char) -> Convert.ToUInt16(x)) (arg.ToCharArray()) in
    String([|for num in numArr do if num >= 32us && num <= 126us then yield Convert.ToChar(num) |])
//end stripExtended

[<EntryPoint>]
let main args =
    let test = "string of ☺☻♥♦⌂, may include control characters and other ilk.♫☼§►↔◄"
    printfn "Original: %s" test
    printfn "Stripped of controls: %s" (stripControl test)
    printfn "Stripped of extended: %s" (stripExtended test)
    0//main must return integer, much like in C/C++


def str = "\t\n\t   A string with\nwhitespace\n\n\t   ";
WriteLine(str.TrimStart());
WriteLine(str.TrimEnd());
WriteLine(str.Trim());      // both ends at once, of course, internal whitespace is preserved in all 3


/* NetRexx */
options replace format comments java crossref symbols nobinary

runSample(arg)
return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method stripWhitespace(sstring, soption = 'BOTH') public static
  wsChars = getWhitspaceCharacterString()
  po1 = sstring.verify(wsChars)
  if po1 = 0 then do
    sstring = ''
    end
  else do
    po2 = sstring.length - (sstring.reverse().verify(wsChars) - 1) + 1
    ss = sstring
    parse ss sl =(po1) sm =(po2) st
    if po1 <= 1 then sl = ''
    soption = soption.upper()
    select
      when 'BOTH'.abbrev(soption, 1)     then sstring = sm
      when 'LEADING'.abbrev(soption, 1)  then sstring = sm || st
      when 'TRAILING'.abbrev(soption, 1) then sstring = sl || sm
      otherwise                               sstring = sm
      end
    end
  return sstring

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
 * Create an array containing a useful subset of unicode whitespace characters
 *
 * @return an array of unicode whitespace characters
 * @see http://www.fileformat.info/info/unicode/category/index.htm
 */
method getWhitspaceCharacters() public static returns Rexx[]
  wsChars = [ -
    /* LINE SEPARATOR              [Zi] */ '\u2028', /* PARAGRAPH SEPARATOR         [Zp] */ '\u2029', -
    /* SPACE                       [Zs] */ '\u0020', /* NO-BREAK SPACE              [Zs] */ '\u00A0', -
    /* OGHAM SPACE MARK            [Zs] */ '\u1680', /* MONGOLIAN VOWEL SEPARATOR   [Zs] */ '\u180E', -
    /* EN QUAD                     [Zs] */ '\u2000', /* EM QUAD                     [Zs] */ '\u2001', -
    /* EN SPACE                    [Zs] */ '\u2002', /* EM SPACE                    [Zs] */ '\u2003', -
    /* THREE-PER-EM SPACE          [Zs] */ '\u2004', /* FOUR-PER-EM SPACE           [Zs] */ '\u2005', -
    /* SIX-PER-EM SPACE            [Zs] */ '\u2006', /* FIGURE SPACE                [Zs] */ '\u2007', -
    /* PUNCTUATION SPACE           [Zs] */ '\u2008', /* THIN SPACE                  [Zs] */ '\u2009', -
    /* HAIR SPACE                  [Zs] */ '\u200A', /* NARROW NO-BREAK SPACE       [Zs] */ '\u202F', -
    /* MEDIUM MATHEMATICAL SPACE   [Zs] */ '\u3000', /* IDIOGRAPHIC SPACE           [Zs] */ '\u205F', -
    /* BACKSPACE                   [Cc] */ '\u0008', /* CHARACTER TABULATION, HT    [Cc] */ '\u0009', -
    /* LINE FEED (LF)              [Cc] */ '\u000A', /* LINE TABULATION (VT)        [Cc] */ '\u000B', -
    /* FORM FEED (FF)              [Cc] */ '\u000C', /* CARRIAGE RETURN (CR)        [Cc] */ '\u000D', -
    /* INFORMATION SEPARATOR FOUR  [Cc] */ '\u001C', /* INFORMATION SEPARATOR THREE [Cc] */ '\u001D', -
    /* INFORMATION SEPARATOR TWO   [Cc] */ '\u001E', /* INFORMATION SEPARATOR ONE   [Cc] */ '\u001F', -
    /* NEXT LINE (NEL)             [Cc] */ '\u0085', -
    /* ZERO WIDTH SPACE            [Cf] */ '\u200B', /* ZERO WIDTH NO-BREAK SPACE   [Cf] */ '\uFEFF'  -
    ]
  return wsChars

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method getWhitspaceCharacterString() public static returns Rexx
  wsCharstring = ''
  loop wsChar over getWhitspaceCharacters()
    wsCharstring = wsCharstring || wsChar
    end wsChar
  return wsCharstring

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) public static
  sstrings = [ -
    ' \u0020 \u0009 \u000D\r \n \u2029\uFEFF1 String with white space.  \t  \r  \n \u1680  ', -
    ' \t 2 String with white space. \t   ', -
    '3 String with white space. \t', -
    ' \t 4 String with white space.', -
    '5 String with white space.', -
    '\u0020\u0009\u2029\uFEFF\u1680\u2006', -
    '   ', -
    '' -
    ]
  loop sstringO over sstrings
    sstringL = stripWhitespace(sstringO, 'l')
    sstringT = stripWhitespace(sstringO, 't')
    sstringB = stripWhitespace(sstringO)
    say '  Original string  ['sstringO']'
    say '    strip leading  ['sstringL']'
    say '    strip trailing ['sstringT']'
    say '    strip both     ['sstringB']'
    say
    end sstringO

  return


100 DECLARE EXTERNAL FUNCTION FNstripcomment$
110 LET marker$="#;"
120 PRINT """";FNstripcomment$("apples, pears # and bananas", marker$);""""
130 PRINT """";FNstripcomment$("apples, pears ; and bananas", marker$);""""
140 PRINT """";FNstripcomment$("   apples, pears   ", marker$);""""
150 END
160 !
170 EXTERNAL FUNCTION FNstripcomment$(text$, delim$)
180 FOR I=1 TO LEN(delim$)
190    LET D = POS(text$, delim$(I:I))
200    IF D>0 THEN LET text$ = text$(1:D-1)
210 NEXT I
220 LET FNstripcomment$=RTRIM$(text$)
230 END FUNCTION


(   "    apples, pears # and bananas
       oranges, mangos ; and a durian"
  : ?text
& :?newText
& ( non-blank
  = %@:~(" "|\t|\r|\n)
  )
& ( cleanUp
  =
    .   @(!arg:?arg ("#"|";") ?)
      & @(rev$!arg:? (!non-blank ?:?arg))
      & @(rev$!arg:? (!non-blank ?:?arg))
      & !arg    {You could write & "[" !arg "]" to prove that the blanks are stripped.}
  )
&   whl
  ' ( @(!text:?line (\r|\n) ?text)
    & !newText \n cleanUp$!line:?newText
    )
& !newText \n cleanUp$!text:?newText
& out$(str$!newText)
);


#include<stdio.h>

int main()
{
	char ch, str[100];
	int i;

	do{
		printf("\nEnter the string :");
		fgets(str,100,stdin);
		for(i=0;str[i]!=00;i++)
		{
			if(str[i]=='#'||str[i]==';')
			{
				str[i]=00;
				break;
			}
		}
		printf("\nThe modified string is : %s",str);
		printf("\nDo you want to repeat (y/n): ");
		scanf("%c",&ch);
		fflush(stdin);
	}while(ch=='y'||ch=='Y');

	return 0;
}


#!/usr/bin/perl -w
use strict ;
use warnings ;

open( FH , "<" , "samplecode.txt" ) or die "Can't open file!$!\n" ;
my $code = "" ;
{
   local $/ ;
   $code = <FH> ; #slurp mode
}
close FH ;
$code =~ s,/\*.*?\*/,,sg ;
print $code . "\n" ;


with javascript_semantics
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 true do
        integer startp = match(startc,text), endp
        if startp=0 then exit end if
        endp = match(endc,text,startp+length(startc))
        assert(endp!=0,"error")
        text[startp..endp+length(endc)-1] = ""
    end while
    return text
end function

puts(1,strip_comments(test))


USING: ascii kernel sequences ;

: strip-control-codes ( str -- str' ) [ control? not ] filter ;

: strip-control-codes-and-extended ( str -- str' )
    strip-control-codes [ ascii? ] filter ;


: strip ( buf len -- buf len' )  \ repacks buffer, so len' <= len
  over + over swap over ( buf dst limit src )
  do
    i [email protected] 32 127 within if
      i [email protected] over c! char+
    then
  loop
  over - ;


module stripcharacters
implicit none

contains

  pure logical function not_control(ch)
    character, intent(in) :: ch
    not_control = iachar(ch) >= 32 .and. iachar(ch) /= 127
  end function not_control

  pure logical function not_extended(ch)
    character, intent(in) :: ch
    not_extended = iachar(ch) >= 32 .and. iachar(ch) < 127
  end function not_extended

  pure function strip(string,accept) result(str)
    character(len=*), intent(in) :: string
    character(len=len(string))   :: str
    interface
      pure logical function accept(ch)
        character, intent(in) :: ch
      end function except
    end interface
    integer :: i,n
    str = repeat(' ',len(string))
    n = 0
    do i=1,len(string)
      if ( accept(string(i:i)) ) then
        n = n+1
        str(n:n) = string(i:i)
      end if
    end do
  end function strip

end module stripcharacters

program test
  use stripcharacters

  character(len=256) :: string, str
  integer            :: ascii(256), i
  forall (i=0:255) ascii(i) = i
  forall (i=1:len(string)) string(i:i) = achar(ascii(i))
  write (*,*) string

  write (*,*) 'Control characters deleted:'
  str = strip(string,not_control)
  write (*,*) str

  forall (i=1:len(string)) string(i:i) = achar(ascii(i))
  write (*,*) 'Extended characters deleted:'
  write (*,*) strip(string,not_extended)
end program test


(setq str "   this is a string   ")

;; trim leading blanks
(trim str " " "")

;; trim trailing blanks
(trim str "" " ")

;; trim both leading and trailing blanks
(trim str)


import strutils

let s = "\t \v \r String with spaces \n \t \f"
echo "“", s, "”"
echo("*** Stripped of leading spaces ***")
echo "“", s.strip(trailing = false), "”"
echo("*** Stripped of trailing spaces ***")
echo "“", s.strip(leading = false), "”"
echo("*** Stripped of leading and trailing spaces ***")
echo "“", s.strip(), "”"


MODULE Trim;
IMPORT Out,Strings,SYSTEM;

CONST
	(* whitespaces *)
	HT = 09X;	VT = 0BX;	FF = 0CX;	GS = 1DX;	US = 1FX;
	LF = 0AX;	CR = 0DX; 	FS = 1CX;	RS = 1EX;	SPC = 20X;

PROCEDURE LTrim(VAR s: ARRAY OF CHAR);
VAR
	j : INTEGER;
BEGIN
	j := 0;
	WHILE (s[j] = HT) OR (s[j] = LF) OR (s[j] = VT) OR (s[j] = CR) OR
		(s[j] = FF) OR (s[j] = FS) OR (s[j] = FS) OR (s[j] = GS) OR
		(s[j] = RS) OR (s[j] = US) OR (s[j] = SPC) DO INC(j) END;
	SYSTEM.MOVE(SYSTEM.ADR(s[j]),SYSTEM.ADR(s[0]),LEN(s) - j);
END LTrim;

PROCEDURE RTrim(VAR s: ARRAY OF CHAR);
VAR
	j : INTEGER;
BEGIN
	j := LEN(s) - 1;
	WHILE (j >= 0) & (s[j] = 0X) DO DEC(j) END;
	WHILE (j >= 0) & ((s[j] = HT) OR (s[j] = LF) OR (s[j] = VT) OR (s[j] = CR) OR
		(s[j] = FF) OR (s[j] = FS) OR (s[j] = FS) OR (s[j] = GS) OR
		(s[j] = RS) OR (s[j] = US) OR (s[j] = SPC)) DO
		s[j] := 0X;
 		DEC(j)
	END
END RTrim;

PROCEDURE Trim(VAR s: ARRAY OF CHAR);
BEGIN
	LTrim(s);
	RTrim(s)
END Trim;

VAR
	s: ARRAY 100 OF CHAR;

BEGIN
	s := "   A AAA";
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);LTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
	s := "AAA A    ";
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);RTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
	s := "   A AA A   ";
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);Trim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
	s := "    ";
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);Trim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
	s := "    ";
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);RTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
	s := "    ";
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);LTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);RTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
	Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);LTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln;
END Trim.


using System.Text.RegularExpressions;

string RemoveComments(string str, string delimiter)
        {
            //regular expression to find a character (delimiter) and
            //      replace it and everything following it with an empty string.
            //.Trim() will remove all beginning and ending white space.
            return Regex.Replace(str, delimiter + ".+", string.Empty).Trim();
        }