#include <iostream>
#include <string>

std::string strip_white(const std::string& input)
{
   size_t b = input.find_first_not_of(' ');
   if (b == std::string::npos) b = 0;
   return input.substr(b, input.find_last_not_of(' ') + 1 - b);
}

std::string strip_comments(const std::string& input, const std::string& delimiters)
{
   return strip_white(input.substr(0, input.find_first_of(delimiters)));
}

int main( ) {
   std::string input;
   std::string delimiters("#;");
   while ( getline(std::cin, input) && !input.empty() ) {
      std::cout << strip_comments(input, delimiters) << std::endl ;
   }
   return 0;
}


> (apply str (take-while #(not (#{\# \;} %)) "apples # comment"))
"apples "


function strip_block_comments( $test_string ) {
	$pattern = "/^.*?(\K\/\*.*?\*\/)|^.*?(\K\/\*.*?^.*\*\/)$/mXus";
	return preg_replace( $pattern, '', $test_string );
}

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

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


(in "sample.txt"
   (while (echo "/*")
      (out "/dev/null" (echo "*/")) ) )


/* A program to remove comments from text. */
strip: procedure options (main);                   /* 8/1/2011 */
   declare text character (80) varying;
   declare (j, k) fixed binary;

   on endfile (sysin) stop;

   do forever;
      get edit (text) (L);
      do until (k = 0);
         k = index(text, '/*');
         if k > 0 then /* we have a start of comment. */
            do;
               /* Look for end of comment. */
               j = index(text, '*/', k+2);
               if j > 0 then
                  do;
                     text = substr(text, 1, k-1) ||
                            substr(text, j+2, length(text)-(j+2)+1);
                  end;
               else
                  do; /* The comment continues onto the next line. */
                     put skip list ( substr(text, 1, k-1) );
more:                get edit (text) (L);
                     j = index(text, '*/');
                     if j = 0 then do; put skip; go to more; end;
                     text = substr(text, j+2, length(text) - (j+2) + 1);
                  end;
            end;
      end;
      put skip list (text);
   end;

end strip;


:- system:set_prolog_flag(double_quotes,codes) .

strip_block_comments(INPUTz)
:-
strip_block_comments(INPUTz,OUTPUTz) ,
system:format("```~n",[OUTPUTz]) ,
system:format("~s~n",[OUTPUTz]) ,
system:format("```~n",[OUTPUTz])
.

strip_block_comments(INPUTz,OUTPUTz)
:-
prolog:phrase(block(OUTPUTz),INPUTz)
.

block([]) --> \+ [_] , ! .
block([CODE|OUTPUTz]) --> \+ comment , ! , [CODE] , block(OUTPUTz) .
block(OUTPUTz) --> comment , ! , block(OUTPUTz) .

comment --> comment_entr , zero_or_more(comment_each) , comment_exit .
comment_entr --> "/*" .
comment_each --> comment , ! .
comment_each --> \+ comment_exit , ! , [_] .
comment_exit --> "*/" .

zero_or_more(CALLABLE) --> call(CALLABLE) , ! , zero_or_more(CALLABLE) .
zero_or_more(_) --> ! .


' FB 1.05.0 Win64

Function stripControlChars(s As Const String) As String
  If s = "" Then Return ""
  Dim count As Integer = 0
  Dim strip(0 To Len(s) - 1) As Boolean
  For i As Integer = 0 To Len(s) - 1
    For j As Integer = 0 To 31
      If s[i] = j OrElse s[i] = 127 Then
        count += 1
        strip(i) = True
        Exit For
      End If
    Next j
  Next i

  Dim buffer As String = Space(Len(s) - count)
  count  = 0
  For i As Integer = 0 To Len(s) - 1
    If Not Strip(i) Then
      buffer[count] = s[i]
      count += 1
    End If
  Next
  Return buffer
End Function

Function stripExtendedChars(s As Const String) As String
  If s = "" Then Return ""
  Dim count As Integer = 0
  Dim strip(0 To Len(s) - 1) As Boolean
  For i As Integer = 0 To Len(s) - 1
    For j As Integer = 128 To 255
      If s[i] = j Then
        count += 1
        strip(i) = True
        Exit For
      End If
    Next j
  Next i

  Dim buffer As String = Space(Len(s) - count)
  count  = 0
  For i As Integer = 0 To Len(s) - 1
    If Not Strip(i) Then
      buffer[count] = s[i]
      count += 1
    End If
  Next
  Return buffer
End Function

Dim s  As String = !"\v\001The\t quick\255 \vbrown\127\f fox\156"
Dim s1 As String = stripControlChars(s)
Dim s2 As String = stripExtendedChars(s)
Dim s3 As String = stripExtendedChars(s1)

' Under Windows console, code page 850 :
' "vertical tab" displays as ♂
' "form feed" displays as ♀
' Chr(1) displays as ☺
' Chr(127) displays as ⌂
' the other control characters do what it says on the tin
' Chr(156) displays as £
' Chr(255) displays as space

Print "Before stripping   :" , s
Print "Ctl chars stripped :" , s1
Print "Ext chars stripped :" , s2
Print "Both sets stripped :" , s3
Print
Print "Before stripping"   ,  "Length => " ; Len(s)
Print "Ctl chars stripped" ,  "Length => " ; Len(s1)
Print "Ext chars stripped" ,  "Length => " ; Len(s2)
Print "Both sets stripped" ,  "Length => " ; Len(s3)
Print
Print "Press any key to quit"
Sleep


#import <Foundation/Foundation.h>

@interface NSString (RCExt)
-(NSString *) ltrim;
-(NSString *) rtrim;
-(NSString *) trim;
@end

@implementation NSString (RCExt)
-(NSString *) ltrim
{
  NSInteger i;
  NSCharacterSet *cs = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  for(i = 0; i < [self length]; i++)
  {
    if ( ![cs characterIsMember: [self characterAtIndex: i]] ) break;
  }
  return [self substringFromIndex: i];
}

-(NSString *) rtrim
{
  NSInteger i;
  NSCharacterSet *cs = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  for(i = [self length] -1; i >= 0; i--)
  {
    if ( ![cs characterIsMember: [self characterAtIndex: i]] ) break;
  }
  return [self substringToIndex: (i+1)];
}

-(NSString *) trim
{
  return [self
	   stringByTrimmingCharactersInSet:
	     [NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
@end

int main()
{
  @autoreleasepool {

    NSString *s = @"     this is a string     ";

    NSLog(@"'%@'", s);
    NSLog(@"'%@'", [s ltrim]);
    NSLog(@"'%@'", [s rtrim]);
    NSLog(@"'%@'", [s trim]);

  }
  return 0;
}


let left_pos s len =
  let rec aux i =
    if i >= len then None
    else match s.[i] with
    | ' ' | '\n' | '\t' | '\r' -> aux (succ i)
    | _ -> Some i
  in
  aux 0

let right_pos s len =
  let rec aux i =
    if i < 0 then None
    else match s.[i] with
    | ' ' | '\n' | '\t' | '\r' -> aux (pred i)
    | _ -> Some i
  in
  aux (pred len)

let trim s =
  let len = String.length s in
  match left_pos s len, right_pos s len with
  | Some i, Some j -> String.sub s i (j - i + 1)
  | None, None -> ""
  | _ -> assert false

let ltrim s =
  let len = String.length s in
  match left_pos s len with
  | Some i -> String.sub s i (len - i)
  | None -> ""

let rtrim s =
  let len = String.length s in
  match right_pos s len with
  | Some i -> String.sub s 0 (i + 1)
  | None -> ""


       identification division.
       program-id. StripComments.

       data division.
       working-storage section.
       01  line-text              pic x(64).

       procedure division.
       main.
           move "apples, pears # and bananas" to line-text
           perform show-striped-text

           move "apples, pears ; and bananas" to line-text
           perform show-striped-text

           stop run
           .
       show-striped-text.
           unstring line-text delimited by "#" or ";" into line-text
           display quote, function trim(line-text), quote
           .


(defun strip-comments (s cs)
  "Truncate s at the first occurrence of a character in cs."
  (defun comment-char-p (c)
    (some #'(lambda (x) (char= x c)) cs))
  (let ((pos (position-if #'comment-char-p s)))
    (subseq s 0 pos)))


import std.stdio, std.regex;

string remove1LineComment(in string s, in string pat=";#") {
    const re = "([^" ~ pat ~ "]*)([" ~ pat ~ `])[^\n\r]*([\n\r]|$)`;
    return s.replace(regex(re, "gm"), "$1$3");
}

void main() {
    const s = "apples, pears # and bananas
apples, pears ; and bananas ";

    writeln(s, "\n====>\n", s.remove1LineComment());
}


Procedure.s escapeChars(text.s)
  Static specialChars.s = "[\^$.|?*+()"
  Protected output.s, nextChar.s, i, countChar = Len(text)
  For i = 1 To countChar
    nextChar = Mid(text, i, 1)
    If FindString(specialChars, nextChar, 1)
      output + "\" + nextChar
    Else
      output + nextChar
    EndIf
  Next
  ProcedureReturn output
EndProcedure

Procedure.s stripBlocks(text.s, first.s, last.s)
  Protected delimter_1.s = escapeChars(first), delimter_2.s = escapeChars(last)
  Protected expNum = CreateRegularExpression(#PB_Any, delimter_1 + ".*?" + delimter_2, #PB_RegularExpression_DotAll)
  Protected output.s = ReplaceRegularExpression(expNum, text, "")
  FreeRegularExpression(expNum)
  ProcedureReturn output
EndProcedure

Define source.s
source.s = "  /**" + #CRLF$
source.s + "   * Some comments" + #CRLF$
source.s + "   * longer comments here that we can parse." + #CRLF$
source.s + "   *" + #CRLF$
source.s + "   * Rahoo " + #CRLF$
source.s + "   */" + #CRLF$
source.s + "   function subroutine() {" + #CRLF$
source.s + "    a = /* inline comment */ b + c ;" + #CRLF$
source.s + "   }" + #CRLF$
source.s + "   /*/ <-- tricky comments */" + #CRLF$
source.s + "" + #CRLF$
source.s + "   /**" + #CRLF$
source.s + "    * Another comment." + #CRLF$
source.s + "    */" + #CRLF$
source.s + "    function something() {" + #CRLF$
source.s + "    }" + #CRLF$

If OpenConsole()
  PrintN("--- source ---")
  PrintN(source)
  PrintN("--- source with block comments between '/*' and '*/' removed ---")
  PrintN(stripBlocks(source, "/*", "*/"))
  PrintN("--- source with block comments between '*' and '*' removed ---")
  PrintN(stripBlocks(source, "*", "*"))

  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


def _commentstripper(txt, delim):
    'Strips first nest of block comments'

    deliml, delimr = delim
    out = ''
    if deliml in txt:
        indx = txt.index(deliml)
        out += txt[:indx]
        txt = txt[indx+len(deliml):]
        txt = _commentstripper(txt, delim)
        assert delimr in txt, 'Cannot find closing comment delimiter in ' + txt
        indx = txt.index(delimr)
        out += txt[(indx+len(delimr)):]
    else:
        out = txt
    return out

def commentstripper(txt, delim=('/*', '*/')):
    'Strips nests of block comments'

    deliml, delimr = delim
    while deliml in txt:
        txt = _commentstripper(txt, delim)
    return txt


stripExtended[str] := str =~ %s/[^\u0020-\u007e]//g

stripControl[str]  := str =~ %s/[\u0000-\u001F\u007f]//g

println[stripExtended[char[0 to 127]]]
println[stripControl[char[0 to 127]]]


Public Sub Main()
Dim sString As String = "The\t \equick\n \fbrownfox \vcost £125.00 or €145.00 or $160.00 \bto \ncapture ©®"
Dim sStd, sExtend As String
Dim siCount As Short

For siCount = 32 To 126
  sStd &= Chr(siCount)
Next

For siCount = 128 To 255
  sExtend &= Chr(siCount)
Next

Print "Original string: -\t" & sString & gb.NewLine
Print "No extended characters: -\t" & Check(sString, sStd)
sStd &= sExtend
Print "With extended characters: -\t" & Check(sString, sStd)

End
'________________________________________________________________
Public Sub Check(sString As String, sCheck As String) As String
Dim siCount As Short
Dim sResult As String

For siCount = 1 To Len(sString)
  If InStr(sCheck, Mid(sString, siCount, 1)) Then sResult &= Mid(sString, siCount, 1)
Next

Return sResult

End


package main

import (
	"golang.org/x/text/transform"
	"golang.org/x/text/unicode/norm"
	"fmt"
	"strings"
)

// two byte-oriented functions identical except for operator comparing c to 127.
func stripCtlFromBytes(str string) string {
	b := make([]byte, len(str))
	var bl int
	for i := 0; i < len(str); i++ {
		c := str[i]
		if c >= 32 && c != 127 {
			b[bl] = c
			bl++
		}
	}
	return string(b[:bl])
}

func stripCtlAndExtFromBytes(str string) string {
	b := make([]byte, len(str))
	var bl int
	for i := 0; i < len(str); i++ {
		c := str[i]
		if c >= 32 && c < 127 {
			b[bl] = c
			bl++
		}
	}
	return string(b[:bl])
}

// two UTF-8 functions identical except for operator comparing c to 127
func stripCtlFromUTF8(str string) string {
	return strings.Map(func(r rune) rune {
		if r >= 32 && r != 127 {
			return r
		}
		return -1
	}, str)
}

func stripCtlAndExtFromUTF8(str string) string {
	return strings.Map(func(r rune) rune {
		if r >= 32 && r < 127 {
			return r
		}
		return -1
	}, str)
}

// Advanced Unicode normalization and filtering,
// see http://blog.golang.org/normalization and
// http://godoc.org/golang.org/x/text/unicode/norm for more
// details.
func stripCtlAndExtFromUnicode(str string) string {
	isOk := func(r rune) bool {
		return r < 32 || r >= 127
	}
	// The isOk filter is such that there is no need to chain to norm.NFC
	t := transform.Chain(norm.NFKD, transform.RemoveFunc(isOk))
	// This Transformer could also trivially be applied as an io.Reader
	// or io.Writer filter to automatically do such filtering when reading
	// or writing data anywhere.
	str, _, _ = transform.String(t, str)
	return str
}

const src = "déjà vu" + // precomposed unicode
	"\n\000\037 \041\176\177\200\377\n" + // various boundary cases
	"as⃝df̅" // unicode combining characters

func main() {
	fmt.Println("source text:")
	fmt.Println(src)
	fmt.Println("\nas bytes, stripped of control codes:")
	fmt.Println(stripCtlFromBytes(src))
	fmt.Println("\nas bytes, stripped of control codes and extended characters:")
	fmt.Println(stripCtlAndExtFromBytes(src))
	fmt.Println("\nas UTF-8, stripped of control codes:")
	fmt.Println(stripCtlFromUTF8(src))
	fmt.Println("\nas UTF-8, stripped of control codes and extended characters:")
	fmt.Println(stripCtlAndExtFromUTF8(src))
	fmt.Println("\nas decomposed and stripped Unicode:")
	fmt.Println(stripCtlAndExtFromUnicode(src))
}


DEF VAR cc AS CHAR INIT "   string with spaces   ".

MESSAGE
   "|" + LEFT-TRIM( cc )  + "|" SKIP
   "|" + RIGHT-TRIM( cc ) + "|" SKIP
   "|" + TRIM( cc )       + "|"
VIEW-AS ALERT-BOX.


sub ltrim { shift =~ s/^\s+//r }
sub rtrim { shift =~ s/\s+$//r }
sub trim { ltrim rtrim shift }

# Usage:
my $p = "       this is a string      ";
print "'", $p, "'\n";
print "'", trim($p), "'\n";
print "'", ltrim($p), "'\n";
print "'", rtrim($p), "'\n";


with javascript_semantics
constant s = "\t test \n"
?s
?trim_head(s)
?trim_tail(s)
?trim(s)


program StripComments;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function DoStripComments(const InString: string; const CommentMarker: Char): string;
begin
  Result := Trim(Copy(InString,1,Pos(CommentMarker,InString)-1));
end;

begin
  Writeln('apples, pears # and bananas --> ' + DoStripComments('apples, pears # and bananas','#'));
  Writeln('');
  Writeln('apples, pears ; and bananas --> ' + DoStripComments('apples, pears ; and bananas',';'));
  Readln;
end.


function StripComments(s : String) : String;
begin
   var p := FindDelimiter('#;', s);
   if p>0 then
      Result := Trim(Copy(s, 1, p-1))
   else Result := Trim(s);
end;

PrintLn(StripComments('apples, pears # and bananas'));
PrintLn(StripComments('apples, pears ; and bananas'));


-module( strip_comments_from_string ).

-export( [task/0] ).

task() ->
    io:fwrite( "~s~n", [keep_until_comment("apples, pears and bananas")] ),
    io:fwrite( "~s~n", [keep_until_comment("apples, pears # and bananas")] ),
    io:fwrite( "~s~n", [keep_until_comment("apples, pears ; and bananas")] ).

keep_until_comment( String ) ->	lists:takewhile( fun not_comment/1, String ).

not_comment( $# ) -> false;
not_comment( $; ) -> false;
not_comment( _ ) -> true.


#lang at-exp racket

;; default delimiters (strings -- not regexps)
(define comment-start-str "/*")
(define comment-end-str "*/")

(define (strip-comments text [rx1 comment-start-str] [rx2 comment-end-str])
  (regexp-replace* (~a (regexp-quote rx1) ".*?" (regexp-quote rx2))
                   text ""))

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

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


sample().split(/ '/*' .+? '*/' /).print;

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

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


/* REXX ***************************************************************
* Split comments
* This program ignores comment delimiters within literal strings
* such as, e.g., in b = "--' O'Connor's widow --";
* it does not (yet) take care of -- comments (ignore rest of line)
* also it does not take care of say 667/*yuppers*/77 (REXX specialty)
*   courtesy GS discussion!
* 12.07.2013 Walter Pachl
**********************************************************************/
fid='in.txt'                           /* input text                 */
oic='oc.txt'; 'erase' oic              /* will contain comments      */
oip='op.txt'; 'erase' oip              /* will contain program parts */
oim='om.txt'; 'erase' oim              /* oc.txt merged with op.txt  */
cmt=0                                  /* comment nesting            */
str=''                                 /* ' or " when in a string    */
Do ri=1 By 1 While lines(fid)>0        /* loop over input            */
  l=linein(fid)                        /* an input line              */
  oc=''                                /* initialize line for oc.txt */
  op=''                                /* initialize line for op.txt */
  i=1                                  /* start at first character   */
  Do While i<=length(l)                /* loop through input line    */
    If cmt=0 Then Do                   /* we are not in a comment    */
      If str<>'' Then Do               /* we are in a string         */
        If substr(l,i,1)=str Then Do   /* string character           */
          If substr(l,i+1,1)=str Then Do /* another one              */
            Call app 'P',substr(l,i,2) /* add '' or "" to op         */
            i=i+2                      /* increase input pointer     */
            Iterate                    /* proceed in input line      */
            End
          Else Do                      /* end of literal string      */
            Call app 'P',substr(l,i,1) /* add ' or " to op           */
            str=' '                    /* no longer in string        */
            i=i+1                      /* increase input pointer     */
            Iterate                    /* proceed in input line      */
            End
          End
        End
      End
    Select
      When str='' &,                   /* not in a string            */
           substr(l,i,2)='/*' Then Do  /* start of comment           */
        cmt=cmt+1                      /* increase commenr nesting   */
        Call app 'C','/*'              /* copy to oc                 */
        i=i+2                          /* increase input pointer     */
        End
      When cmt=0 Then Do               /* not in a comment           */
        If str=' ' Then Do             /* not in a string            */
          If pos(substr(l,i,1),'''"')>0 Then /* string delimiter     */
            str=substr(l,i,1)          /* remember that              */
          End
        Call app 'P',substr(l,i,1)     /* copy to op                 */
        i=i+1                          /* increase input pointer     */
        End
      When substr(l,i,2)='*/' Then Do  /* end of comment             */
        cmt=cmt-1                      /* decrement nesting depth    */
        Call app 'C','*/'              /* copy to oc                 */
        i=i+2                          /* increase input pointer     */
        End
      Otherwise Do                     /* any other character        */
        Call app 'C',substr(l,i,1)     /* copy to oc                 */
        i=i+1                          /* increase input pointer     */
        End
      End
    End
  Call oc                              /* Write line oc              */
  Call op                              /* Write line op              */
  End
Call lineout oic                       /* Close File oic             */
Call lineout oip                       /* Close File oip             */

Do ri=1 To ri-1                        /* merge program with comments*/
  op=linein(oip)
  oc=linein(oic)
  Do i=1 To length(oc)
    If substr(oc,i,1)<>'' Then
      op=overlay(substr(oc,i,1),op,i,1)
    End
  Call lineout oim,op
  End
Call lineout oic
Call lineout oip
Call lineout oim
Exit

app: Parse Arg which,string
/* add str to oc or op                                               */
/* and corresponding blanks to the other (op or oc)                  */
If which='C' Then Do
  oc=oc||string
  op=op||copies(' ',length(string))
  End
Else Do
  op=op||string
  oc=oc||copies(' ',length(string))
  End
Return

oc: Return lineout(oic,oc)
op: Return lineout(oip,op)


def stripControl = { it.replaceAll(/\p{Cntrl}/, '') }
def stripControlAndExtended = { it.replaceAll(/[^\p{Print}]/, '') }


import Control.Applicative (liftA2)

strip, strip2 :: String -> String
strip = filter (liftA2 (&&) (> 31) (< 126) . fromEnum)

-- or
strip2 = filter (((&&) <$> (> 31) <*> (< 126)) . fromEnum)

main :: IO ()
main =
  (putStrLn . unlines) $
  [strip, strip2] <*> ["alphabetic 字母 with some less parochial parts"]


procedure main(A)
write(image(deletec(&ascii,&ascii--(&ascii)[33:127])))
end
link strings


<?php

/**
 * @author Elad Yosifon
 */

$string = '      this is a string     ';
echo '^'.trim($string) .'$'.PHP_EOL;
echo '^'.ltrim($string).'$'.PHP_EOL;
echo '^'.rtrim($string).'$'.PHP_EOL;


import util.

go =>
  S = "     Jabberwocky     ",
  println("<" ++ S ++ ">"),

  println("<" ++ lstrip(S) ++ ">"),
  println("<" ++ rstrip(S) ++ ">"),
  println("<" ++ strip(S) ++ ">"),
  println("<" ++ strip("\t\r\bTwas brillig, and the slithy toves\r  \t\v"," \b\v\t\r\v") ++ ">"),
  nl.


(de trimLeft (Str)
   (pack (flip (trim (flip (chop Str))))) )

(de trimRight (Str)
   (pack (trim (chop Str))) )

(de trimBoth (Str)
   (pack (clip (chop Str))) )


let stripComments s =
    s
    |> Seq.takeWhile (fun c -> c <> '#' && c <> ';')
    |> Seq.map System.Char.ToString
    |> Seq.fold (+) ""


USE: sequences.extras
: strip-comments ( str -- str' )
    [ "#;" member? not ] take-while "" like ;


class Main
{
  static Str removeComment (Str str)
  {
    regex := Regex <|(;|#)|>
    matcher := regex.matcher (str)
    if (matcher.find)
      return str[0..<matcher.start]
    else
      return str
  }

  public static Void main ()
  {
    echo (removeComment ("String with comment here"))
    echo (removeComment ("String with comment # here"))
    echo (removeComment ("String with comment ; here"))
  }
}


\ Rosetta Code Strip Comment

: LASTCHAR ( addr len -- addr len c) 2DUP + [email protected] ;
: COMMENT? ( char -- ? )  S" #;"  ROT SCAN NIP ;    \ test char for "#;"
: -LEADING ( addr len -- addr' len')  BL SKIP ;     \ remove leading space characters

: -COMMENT   ( addr len -- addr len') \ removes # or ; comments
            1-
            BEGIN
              LASTCHAR COMMENT? 0=
            WHILE                     \ while not a comment char...
                1-                    \ reduce length by 1
            REPEAT
            1-  ;                     \ remove 1 more (the comment char)

: -TRAILING  ( adr len -- addr len')   \ remove trailing spaces
             1-
             BEGIN
               LASTCHAR BL =
             WHILE                    \ while lastchar = blank
               1-                     \ reduce length by 1
             REPEAT
             1+ ;

: COMMENT-STRIP ( addr len -- addr 'len) -LEADING -COMMENT -TRAILING  ;


example = "123/*456*/abc/*def*/789"

example2 = example
nr = 1
while nr = 1
      n1 = substr(example2,"/*")
      n2 = substr(example2,"*/")
      if n1 > 0 and n2 > 0
         example3 = substr(example2,n1,n2-n1+2)
         example2 = substr(example2,example3,"")
      else nr = 0 ok
end
see example2 + nl


def remove_comments!(str, comment_start='/*', comment_end='*/')
  while start_idx = str.index(comment_start)
    end_idx = str.index(comment_end, start_idx + comment_start.length) + comment_end.length - 1
    str[start_idx .. end_idx] = ""
  end
  str
end

def remove_comments(str, comment_start='/*', comment_end='*/')
  remove_comments!(str.dup, comment_start, comment_end)
end

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

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

puts remove_comments example


import java.util.regex.Pattern.quote
def strip1(x: String, s: String = "/*", e: String = "*/") =
  x.replaceAll("(?s)"+quote(s)+".*?"+quote(e), "")


$ include "seed7_05.s7i";

const proc: main is func
  local
    const string: stri is "\
        \  /**\n\
        \   * Some comments\n\
        \   * longer comments here that we can parse.\n\
        \   *\n\
        \   * Rahoo\n\
        \   */\n\
        \   function subroutine() {\n\
        \    a = /* inline comment */ b + c ;\n\
        \   }\n\
        \   /*/ <-- tricky comments */\n\
        \\n\
        \   /**\n\
        \    * Another comment.\n\
        \    */\n\
        \    function something() {\n\
        \    }";
  begin
    writeln(replace2(stri, "/*", "*/", " "));
  end func;


stripControlCodes=: -.&(DEL,32{.a.)
stripControlExtCodes=: ([ -. -.)&(32}.127{.a.)


import java.util.function.IntPredicate;

public class StripControlCodes {

    public static void main(String[] args) {
        String s = "\u0000\n abc\u00E9def\u007F";
        System.out.println(stripChars(s, c -> c > '\u001F' && c != '\u007F'));
        System.out.println(stripChars(s, c -> c > '\u001F' && c < '\u007F'));
    }

    static String stripChars(String s, IntPredicate include) {
        return s.codePoints().filter(include::test).collect(StringBuilder::new,
                StringBuilder::appendCodePoint, StringBuilder::append).toString();
    }
}


(function (strTest) {

    // s -> s
    function strip(s) {
        return s.split('').filter(function (x) {
            var n = x.charCodeAt(0);

            return 31 < n && 127 > n;
        }).join('');
    }

    return strip(strTest);

})("\ba\x00b\n\rc\fd\xc3");


put ( trim(text, ' ', '') );          /* trims leading blanks.       */
put ( trim(text, '', ' ') );          /* trims trailing blanks.      */
put ( trim(text) );                   /* trims leading and trailing  */
                                      /* blanks.                     */


$var = " Hello World "
$var.TrimStart() # String with leading whitespace removed
$var.TrimEnd() # String with trailing whitespace removed
$var.Trim() # String with both leading and trailing whitespace removed


strip :-
	In = "    There are unwanted blanks here!    ",
	strip_left(In, OutLeft),
	format('In          : ~s__~n', [In]),
	format('Strip left  : ~s__~n', [OutLeft]),
	strip_right(In, OutRight),
	format('Strip right : ~s__~n', [OutRight]),
	strip(In, Out),
	format('Strip       : ~s__~n', [Out]).

strip_left(In, Out) :-
	strip_action(In, Out, []).

strip_right(In, Out) :-
	reverse(In, RIn),
	strip_left(RIn, ROut),
	reverse(ROut, Out).

strip(In, Out) :-
	strip_left(In, Tmp),
	strip_right(Tmp, Out).

strip_action([X|T]) -->
	{\+code_type(X, graph), !},
	strip_action(T).

strip_action(X) --> X.


' FB 1.05.0 Win64

Sub stripComment(s As String, commentMarkers As String)
  If s = "" Then Return
  Dim i As Integer = Instr(s, Any commentMarkers)
  If i > 0 Then
    s = Left(s, i - 1)
    s = Trim(s) '' removes both leading and trailing whitespace
  End If
End Sub

Dim s(1 To 4) As String = _
{ _
  "apples, pears # and bananas", _
  "apples, pears ; and bananas", _
  "# this is a comment", _
  "  # this is a comment with leading whitespace" _
}

For i As Integer = 1 To 4
  stripComment(s(i), "#;")
  Print s(i), " => Length ="; Len(s(i))
Next

Print
Print "Press any key to quit"
Sleep


package main

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

const commentChars = "#;"

func stripComment(source string) string {
	if cut := strings.IndexAny(source, commentChars); cut >= 0 {
		return strings.TrimRightFunc(source[:cut], unicode.IsSpace)
	}
	return source
}

func main() {
	for _, s := range []string{
		"apples, pears # and bananas",
		"apples, pears ; and bananas",
		"no bananas",
	} {
		fmt.Printf("source:   %q\n", s)
		fmt.Printf("stripped: %q\n", stripComment(s))
	}
}


def stripComments = { it.replaceAll(/\s*[#;].*$/, '') }


func strip_block_comments(code, beg='/*', end='*/') {
    var re = Regex.new(beg.escape + '.*?' + end.escape, 's');
    code.gsub(re, '');
}

say strip_block_comments(ARGF.slurp);


* Program: strip_block_comments.sbl
* To run: sbl -r extract_extension.sbl
* Description: Strip block comments.
*              Can use different begin and end delimiters.
*              Handles comment nesting and unmatched end delimiters.
*              Unmatched begin delimiters remove text to end of file.
*              Does not handle quoted delimiters.
*              Most null lines are removed, which may not be
*              what is desired.
* Comment: Tested using the Spitbol for Linux version of SNOBOL4

* Function strip_block_comments will read a file, or the text after
* the END statement below. Parameter bcom is the beginning comment
* string and parameter ecom is the ending comment string.
*
	define('strip_block_comments(bcom,ecom)break_chars,c,newc,pre,pc,b')
		pat1 = breakx(*break_chars) . pre (*bcom | *gt(b,0) *ecom) . pc
	:(strip_block_comments_end)
strip_block_comments
	break_chars = substr(bcom,1,1) substr(ecom,1,1)
	newc = ""
	b = 0
in1
	c = input :f(p60)

p10
	c ? pat1 = "" :f(p20)

* matches
	le(b,0) :s(leb)f(gtb)
leb
	b = leq(pc,bcom) b + 1 :f(leb2)
	newc = newc pre :(p10)
leb2
	b = leq(pc,ecom) b - 1 :f(error)
	:(p10)
gtb
	b = leq(pc,bcom) b + 1
	b = leq(pc,ecom) b - 1
	:(p10)

* nomatches
p20
	newc = lt(b,1) newc c
	ident(newc) :s(in1)
	:(p50)

p50
	output = newc
	newc = "" :(in1)

p60
	output = differ(newc) newc
	:(return)
strip_block_comments_end

* Set "begin" comment delimiter (bcom) and "end" comment delimiter (ecom) below
	bcom = "/*"
	ecom = "*/"
*	bcom = "{{*"
*	ecom = "?/"

* Strip block comments from the text lines after the END statement
	strip_block_comments(bcom,ecom)

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

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

----------------------------------------------
With nested comments/* Nested /* comment*/s*/*/!
Unmatched"/*" end delimiters simply remove
to end of file


import Foundation

func stripBlocks(from str: String, open: String = "/*", close: String = "*/") -> String {
  guard !open.isEmpty && !close.isEmpty else {
    return str
  }

  var ret = str

  while let begin = ret.range(of: open), let end = ret[begin.upperBound...].range(of: close) {
    ret.replaceSubrange(Range(uncheckedBounds: (begin.lowerBound, end.upperBound)), with: "")
  }

  return ret
}

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

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

print(stripBlocks(from: test))


proc stripBlockComment {string {openDelimiter "/*"} {closeDelimiter "*/"}} {
    # Convert the delimiters to REs by backslashing all non-alnum characters
    set openAsRE [regsub -all {\W} $openDelimiter {\\&}]
    set closeAsRE [regsub -all {\W} $closeDelimiter {\\&}]

    # Now remove the blocks using a dynamic non-greedy regular expression
    regsub -all "$openAsRE.*?$closeAsRE" $string ""
}


def strip_control_codes:
 explode | map(select(. > 31 and . != 127)) | implode;

def strip_extended_characters:
  explode | map(select(31 < . and . < 127)) | implode;


stripc0{T<:String}(a::T) = replace(a, r"[\x00-\x1f\x7f]", "")
stripc0x{T<:String}(a::T) = replace(a, r"[^\x20-\x7e]", "")

a = "a\n\tb\u2102d\u2147f"

println("Original String:\n    ", a)
println("\nWith C0 control characters removed:\n    ", stripc0(a))
println("\nWith C0 and extended characters removed:\n    ", stripc0x(a))


// version 1.1.2

fun String.strip(extendedChars: Boolean = false): String {
    val sb = StringBuilder()
    for (c in this) {
        val i = c.toInt()
        if (i in 32..126 || (!extendedChars && i >= 128)) sb.append(c)
    }
    return sb.toString()
}

fun main(args: Array<String>) {
    println("Originally:")
    val s = "123\tabc\u0007DEF\u007F+-*/€æŧðłþ"
    println("String = $s  Length = ${s.length}")
    println("\nAfter stripping control characters:")
    val t = s.strip()
    println("String = $t  Length = ${t.length}")
    println("\nAfter stripping control and extended characters:")
    val u = s.strip(true)
    println("String = $u  Length = ${u.length}")
}


val .str = "()\x15abcd\uFFFF123\[email protected]#$%^&*\x01"

writeln "original          : ", .str
writeln "without ctrl chars: ", replace(.str, RE/\p{Cc}/, ZLS)
writeln "print ASCII only  : ", replace(.str, re/[^ -~]/, ZLS)


;define the whitespace as desired
#whitespace$ = " " + Chr($9) + Chr($A) + Chr($B) + Chr($C) + Chr($D) + Chr($1C) + Chr($1D) + Chr($1E) + Chr($1F)

Procedure.s myLTrim(source.s)
  Protected i, *ptrChar.Character, length = Len(source)
  *ptrChar = @source
  For i = 1 To length
    If Not FindString(#whitespace$, Chr(*ptrChar\c))
      ProcedureReturn Right(source, length + 1 - i)
    EndIf
    *ptrChar + SizeOf(Character)
  Next
EndProcedure

Procedure.s myRTrim(source.s)
  Protected i, *ptrChar.Character, length = Len(source)
  *ptrChar = @source + (length - 1) * SizeOf(Character)
  For i = length To 1 Step - 1
    If Not FindString(#whitespace$, Chr(*ptrChar\c))
      ProcedureReturn Left(source, i)
    EndIf
    *ptrChar - SizeOf(Character)
  Next
EndProcedure

Procedure.s myTrim(source.s)
  ProcedureReturn myRTrim(myLTrim(source))
EndProcedure

If OpenConsole()
  PrintN(#DQUOTE$ + myLTrim("  Top  ") + #DQUOTE$)
  PrintN(#DQUOTE$ + myRTrim("  Tail  ") + #DQUOTE$)
  PrintN(#DQUOTE$ +  myTrim("  Both  ") + #DQUOTE$)

  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


>>> s = ' \t \r \n String with spaces  \t  \r  \n  '
>>> s
' \t \r \n String with spaces  \t  \r  \n  '
>>> s.lstrip()
'String with spaces  \t  \r  \n  '
>>> s.rstrip()
' \t \r \n String with spaces'
>>> s.strip()
'String with spaces'
>>>


ms = ";#"

main = getContents >>=
    mapM_ (putStrLn . takeWhile (`notElem` ms)) . lines


# strip_comments:
# return part of string up to first character in 'markers',
# or else the whole string if no comment marker is present
procedure strip_comments (str, markers)
  return str ? tab(upto(markers) | 0)
end

procedure main ()
  write (strip_comments ("apples, pears   and bananas", cset ("#;")))
  write (strip_comments ("apples, pears # and bananas", cset ("#;")))
  write (strip_comments ("apples, pears ; and bananas", cset ("#;")))
end


Home is a room.

When play begins:
	strip comments from "apples, pears # and bananas";
	strip comments from "apples, pears ; and bananas";
	end the story.

To strip comments from (T - indexed text):
	say "[T] -> ";
	replace the regular expression "<#;>.*$" in T with "";
	say "[T][line break]".


strip=: [email protected](#~  *./\@:[email protected]&';#')


import java.io.*;

public class StripLineComments{
    public static void main( String[] args ){
	if( args.length < 1 ){
	    System.out.println("Usage: java StripLineComments StringToProcess");
	}
	else{
	    String inputFile = args[0];
	    String input = "";
	    try{
		BufferedReader reader = new BufferedReader( new FileReader( inputFile ) );
		String line = "";
		while((line = reader.readLine()) != null){
		    System.out.println( line.split("[#;]")[0] );
		}
	    }
	    catch( Exception e ){
		e.printStackTrace();
	    }
	}
    }
}


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

   /**
    * Another comment.
    */
    function something() {
    }
$$ MODE TUSCRIPT
ERROR/STOP CREATE ("testfile",SEQ-E,-std-)
ERROR/STOP CREATE ("destfile",SEQ-E,-std-)
FILE "testfile" = script
BUILD S_TABLE commentbeg=":/*:"
BUILD S_TABLE commentend=":*/:"

ACCESS t: READ/STREAM "testfile" s.z/u,a/commentbeg+t+e/commentend,typ
ACCESS d: WRITE/STREAM "destfile" s.z/u,a+t+e
LOOP
READ/EXIT t
IF (typ==3) CYCLE
t=SQUEEZE(t)
WRITE/ADJUST d
ENDLOOP
ENDACCESS/PRINT t
ENDACCESS/PRINT d
d=FILE("destfile")
TRACE *d


'strip block comment NESTED comments
'multi line comments
'and what if there are string literals with these delimeters?
'------------------------
'delimeters for Block Comment can be specified, exactly two characters each
'Three states: Block_Comment, String_Literal, Other_Text
'Globals:
Dim t As String 'target string
Dim s() As Byte 'source array
Dim j As Integer 'index into the source string s, converted to byte array
Dim SourceLength As Integer 'of a base 0 array, so last byte is SourceLength - 1
Dim flag As Boolean
Private Sub Block_Comment(sOpBC As String, sClBC As String)
    'inside a block comment, expecting close block comment delimeter
    flag = False
    Do While j < SourceLength - 2
        Select Case s(j)
            Case Asc(Left(sOpBC, 1))
                If s(j + 1) = Asc(Right(sOpBC, 1)) Then
                    'open block NESTED comment delimeter found
                    j = j + 2
                    Block_Comment sOpBC, sClBC
                End If
            Case Asc(Left(sClBC, 1))
                If s(j + 1) = Asc(Right(sClBC, 1)) Then
                    'close block comment delimeter found
                    flag = True
                    j = j + 2
                    Exit Do
                End If
                'just a lone star
            Case Else
        End Select
        j = j + 1
    Loop
    If Not flag Then MsgBox "Error, missing close block comment delimeter"
End Sub
Private Sub String_Literal()
    'inside as string literal, expecting double quote as delimeter
    flag = False
    Do While j < SourceLength - 2
        If s(j) = Asc("""") Then
            If s(j + 1) = Asc("""") Then
                'found a double quote within a string literal
                t = t + Chr(s(j))
                j = j + 1
            Else
                'close string literal delimeter found
                flag = True
                t = t + Chr(s(j))
                j = j + 1
                Exit Do
            End If
        End If
        t = t + Chr(s(j))
        j = j + 1
    Loop
    If Not flag Then MsgBox "Error, missing closing string delimeter"
End Sub
Private Sub Other_Text(Optional sOpBC As String = "/*", Optional sClBC As String = "*/")
    If Len(sOpBC) <> 2 Then
        MsgBox "Error, open block comment delimeter must be 2" & _
        " characters long, got " & Len(sOpBC) & " characters"
        Exit Sub
    End If
    If Len(sClBC) <> 2 Then
        MsgBox "Error, close block comment delimeter must be 2" & _
        " characters long, got " & Len(sClBC) & " characters"
        Exit Sub
    End If
    Do While j < SourceLength - 1
        Select Case s(j)
            Case Asc(""""):
                t = t + Chr(s(j))
                j = j + 1
                String_Literal
            Case Asc(Left(sOpBC, 1))
                If s(j + 1) = Asc(Right(sOpBC, 1)) Then
                    'open block comment delimeter found
                    j = j + 2
                    Block_Comment sOpBC, sClBC
                Else
                    t = t + Chr(s(j))
                    j = j + 1
                End If
            Case Else
                t = t + Chr(s(j))
                j = j + 1
        End Select
    Loop
    If j = SourceLength - 1 Then t = t + Chr(s(j))
End Sub
Public Sub strip_block_comment()
    Dim n As String
    n = n & "/**" & vbCrLf
    n = n & "* Some comments /*NESTED COMMENT*/" & vbCrLf
    n = n & "* longer comments here that we can parse." & vbCrLf
    n = n & "*" & vbCrLf
    n = n & "* Rahoo" & vbCrLf
    n = n & "*/" & vbCrLf
    n = n & "mystring = ""This is the """"/*"""" open comment block mark.""" & vbCrLf
    'VBA converts two double quotes in a row within a string literal to a single double quote
    'see the output below. Quadruple double quotes become two double quotes within the string
    'to represent a single double quote within a string.
    n = n & "function subroutine() {" & vbCrLf
    n = n & "a = /* inline comment */ b + c ;" & vbCrLf
    n = n & "}" & vbCrLf
    n = n & "/*/ <-- tricky /*NESTED*/ comments */" & vbCrLf
    n = n & "" & vbCrLf
    n = n & "/**" & vbCrLf
    n = n & "* Another comment." & vbCrLf
    n = n & "*/" & vbCrLf
    n = n & "function something() {" & vbCrLf
    n = n & "}"
    s = StrConv(n, vbFromUnicode)
    j = 0
    t = ""
    SourceLength = Len(n)
    Other_Text 'The open and close delimeters for block comment are optional ;)
    Debug.Print "Original text:"
    Debug.Print String$(60, "-")
    Debug.Print n & vbCrLf
    Debug.Print "Text after deleting comment blocks, preserving string literals:"
    Debug.Print String$(60, "-")
    Debug.Print t
End Sub


    all$ =""
    for i =0 to 255
        all$ =all$ +chr$( i)
    next i

    print "Original string of bytes.  ( chr$( 10) causes a CRLF.)"
    print all$
    print

    lessControl$ =controlStripped$( all$)
    print "With control codes stripped out."
    print lessControl$
    print

    lessExtendedAndControl$ =extendedStripped$( lessControl$)
    print "With extended codes stripped out too."
    print lessExtendedAndControl$

    end

    function controlStripped$( i$)
        r$ =""
        for j =1 to len( i$)
            ch$ =mid$( i$, j, 1)
            if asc( ch$) >=32 then r$ =r$ +ch$
        next j
        controlStripped$ =r$
    end function

    function extendedStripped$( i$)
        r$ =""
        for j =1 to len( i$)
            ch$ =mid$( i$, j, 1)
            if asc( ch$) <=128 then r$ =r$ +ch$
        next j
        extendedStripped$ =r$
    end function


function Strip_Control_Codes( str )
    local s = ""
    for i in str:gmatch( "%C+" ) do
 	s = s .. i
    end
    return s
end

function Strip_Control_and_Extended_Codes( str )
    local s = ""
    for i = 1, str:len() do
	if str:byte(i) >= 32 and str:byte(i) <= 126 then
  	    s = s .. str:sub(i,i)
	end
    end
    return s
end

q = ""
for i = 0, 255 do
	q = q .. string.char(i)
end

print( Strip_Control_Codes(q) )
print( Strip_Control_and_Extended_Codes(q) )


/O> [ reverse trim reverse ] is trim-trailing  ( $ --> $ )
... [ trim trim-trailing ]   is trim-both-ends ( $ --> $ )
... $ '   a quick quack   ' echo$ say "!" cr
... $ '   a quick quack   ' trim echo$ say "!" cr
... $ '   a quick quack   ' trim-trailing echo$ say "!" cr
... $ '   a quick quack   ' trim-both-ends echo$ say "!" cr
...
   a quick quack   !
a quick quack   !
   a quick quack!
a quick quack!

Stack empty.


s <- "  Ars  Longa  "

trimws(s)
[1] "Ars  Longa"

trimws(s, "left")
[1] "Ars  Longa  "

trimws(s, "right")
[1] "  Ars  Longa"


#lang racket

;; Using Racket's `string-trim'

(define str "  \n\t foo  bar   \r\n  ")

;; both sides:
(string-trim str) ; -> "foo  bar"

;; one side:
(string-trim str #:right? #f) ; -> "foo  bar   \r\n  "
(string-trim str #:left? #f)  ; -> "  \n\t foo  bar"

;; can also normalize spaces:
(string-normalize-spaces (string-trim str)) ; -> "foo bar"


my $s = "\r\n \t\x2029 Good Stuff \x202F\n";
say $s.trim;
say $s.trim.raku;
say $s.trim-leading.raku;
say $s.trim-trailing.raku;


function stripComments(s) {
  var re1 = /^\s+|\s+$/g;  // Strip leading and trailing spaces
  var re2 = /\s*[#;].+$/g; // Strip everything after # or ; to the end of the line, including preceding spaces
  return s.replace(re1,'').replace(re2,'');
}

var s1 = 'apples, pears # and bananas';
var s2 = 'apples, pears ; and bananas';

alert(stripComments(s1) + '\n' + stripComments(s2));


using Printf

function striplinecomment(a::String, cchars::String="#;")
    b = strip(a)
    0 < length(cchars) || return b
    for c in cchars
        r = Regex(@sprintf "\\%c.*" c)
        b = replace(b, r => "")
    end
    strip(b)
end

tests = ("apples, pears # and bananas",
         "apples, pears ; and bananas",
         "  apples, pears & bananas   ",
         " # ")

for t in tests
    s = striplinecomment(t)
    println("Testing \"", t, "\":")
    println("    \"", s, "\"")
end


// version 1.0.6

val r = Regex("""(/\*.*\*/|//.*$)""")

fun stripComments(s: String) = s.replace(r, "").trim()

fun main(args: Array<String>) {
    val strings = arrayOf(
        "apples, pears // and bananas",
        "   apples, pears /* and bananas */",
        "/* oranges */ apples // pears and bananas  ",
        " \toranges /*apples/*, pears*/*/and bananas"
    )
    for (string in strings) println(stripComments(string))
}


string1$ = "apples, pears # and bananas"
string2$ = "pears;, " + chr$(34) + "apples ; " + chr$(34) + " an;d bananas"
commentMarker$ = "; #"
Print parse$(string2$, commentMarker$)
End

Function parse$(string$, commentMarker$)
    For i = 1 To Len(string$)
        charIn$ = Mid$(string$, i, 1)
        If charIn$ = Chr$(34) Then
            inQuotes = Not(inQuotes)
        End If
        If Instr(commentMarker$, charIn$) And (inQuotes = 0) Then Exit For
    next i
    parse$ = Left$(string$, (i - 1))
End Function


var stripper = Fn.new { |start, end|
    if (start == "" || end == "") {
        start = "/*"
        end   = "*/"
    }
    return Fn.new { |source|
        while (true) {
            var cs = source.indexOf(start)
            if (cs == -1) break
            var ce = source[cs+2..-1].indexOf(end)
            if (ce == -1) break
            source = source[0...cs] + source[cs+ce+4..-1]
        }
        return source
    }
}

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

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

var stripC = stripper.call("", "")
System.print(stripC.call(source))


Proc strip_block_comments
   Parameters string inhalt, beg_delim, end_delim
   Declare long start, ende, anzahl
   start = 1
   start = InStr(beg_delim, inhalt, start)
   While start > 0
      ende = InStr(end_delim, inhalt, start + len(beg_delim))
      If ende > 0
         anzahl = ende +  + len(end_delim) - start
         inhalt = Del$(inhalt, start, anzahl)
      Else
         BREAK
      EndIf
      start = InStr(beg_delim, inhalt, start)
   EndWhile
   Return inhalt
EndProc

Cls
Declare string Text
Text = BlockRead("C:\Temp\Multiline_comment.txt")
Text = strip_block_comments(Text, "/*", "*/")
Print "Output:"
Print Text
WaitKey
End


fcn stripper(text, a="/*", b="*/"){
   while(xy:=text.span(a,b,True)){ x,y:=xy; text=text[0,x] + text[x+y,*] }
   text
}


 function str = stripped(str)
    str = str(31<str & str<127);
  end;


proc stripped(str: string): string =
  result = ""
  for c in str:
    if ord(c) in 32..126:
      result.add c

proc strippedControl(str: string): string =
  result = ""
  for c in str:
    if ord(c) in {32..126, 128..255}:
      result.add c

echo strippedControl "\ba\x00b\n\rc\fdÄ"
echo stripped "\ba\x00b\n\rc\fd\xc3"


let is_control_code c =
  let d = int_of_char c in
  d < 32 || d = 127

let is_extended_char c =
  let d = int_of_char c in
  d > 127

let strip f str =
  let len = String.length str in
  let res = Bytes.create len in
  let rec aux i j =
    if i >= len
    then Bytes.to_string (Bytes.sub res 0 j)
    else if f str.[i]
    then aux (succ i) j
    else begin
      Bytes.set res j str.[i];
      aux (succ i) (succ j)
    end
  in
  aux 0 0

let () =
  Random.self_init ();
  let len = 32 in
  let s =
    String.init len (fun _ ->
      char_of_int (Random.int 256))
  in
  print_endline (strip is_control_code s);
  print_endline (strip (fun c -> (is_control_code c) || (is_extended_char c)) s);
;;


>> trim/head " remove leading white space "
== "remove leading white space "
>> trim/tail " remove trailing white space "
== " remove trailing white space"
>> trim " remove both white spaces "
== "remove both white spaces"


'__this_is_a_test___ s:trim-left
'__this_is_a_test___ s:trim-right
'__this_is_a_test___ s:trim


/*REXX program demonstrates  how to  strip  leading  and/or  trailing  spaces (blanks). */
yyy="   this is a string that has leading/embedded/trailing blanks,  fur shure.  "
say 'YYY──►'yyy"◄──"                             /*display the original string + fence. */
                      /*white space also includes tabs (VT, HT), among other characters.*/

                      /*all examples in each group are equivalent, only the option's 1st*/
                      /*character is examined.                                          */
noL=strip(yyy,'L')                               /*elide any  leading white space.      */
noL=strip(yyy,"l")                               /*  (the same as the above statement.) */
noL=strip(yyy,'leading')                         /*    "    "   "  "    "       "       */
say 'noL──►'noL"◄──"                             /*display the string with a title+fence*/

noT=strip(yyy,'T')                               /*elide any trailing white space.      */
noT=strip(yyy,"t")                               /*  (the same as the above statement.) */
noT=strip(yyy,'trailing')                        /*    "    "   "  "    "       "       */
say 'noT──►'noT"◄──"                             /*display the string with a title+fence*/

noB=strip(yyy)                                   /*elide leading & trailing white space.*/
noB=strip(yyy,)                                  /*  (the same as the above statement.) */
noB=strip(yyy,'B')                               /*    "    "   "  "    "       "       */
noB=strip(yyy,"b")                               /*    "    "   "  "    "       "       */
noB=strip(yyy,'both')                            /*    "    "   "  "    "       "       */
say 'noB──►'noB"◄──"                             /*display the string with a title+fence*/

                                                 /*elide leading & trailing white space,*/
noX=space(yyy)                                   /* including white space between words.*/
say 'nox──►'noX"◄──"                             /*display the string with a title+fence*/
                                                 /*stick a fork in it,  we're all done. */


comment_symbols = ";#"

s1 = "apples, pears # and bananas"
s2 = "apples, pears ; and bananas"

print ( string.match( s1, "[^"..comment_symbols.."]+" ) )
print ( string.match( s2, "[^"..comment_symbols.."]+" ) )


> use StringTools in map( [email protected], [ "\t\t   apples, pears \t# and bananas", " apples, pears ; and bananas  \t" ], "#;" ) end;
                            ["apples, pears", "apples, pears"]


a = "apples, pears # and bananas
  apples, pears ; and bananas";
b = StringReplace[a, RegularExpression["[ ]+[#;].+[\n]"] -> "\n"];
StringReplace[b, RegularExpression["[ ]+[#;].+$"] -> ""] // FullForm


function line = stripcomment(line)
   e = min([find(line=='#',1),find(line==';',1)]);
   if ~isempty(e)
      e = e-1;
      while isspace(line(e)) e = e - 1; end;
      line = line(1:e);
   end;
end;


strip = function(test)
    comment = test.indexOf("#")
    if comment == null then comment = test.indexOf(";")
    if comment then test = test[:comment]
    while test[-1] == " "
        test = test - " "
    end while
    return test
end function

print strip("This is a hash test    # a comment") + "."
print strip("This is a semicolon test   ;  a comment") + "."
print strip("This is a no comment test   ") + "."


program StripCharacters(output);

function Strip (s: string; control, extended: boolean): string;
  var
    index: integer;
  begin
    Strip := '';
    for index:= 1 to length(s) do
    if not ((control and (ord(s[index]) <= 32)) or (extended and (ord(s[index]) > 127))) then
      Strip := Strip + s[index];
  end;

var
  test: string;
  i: integer;

begin
  setlength(test, 40);
  randomize;
  for i := 1 to length(test) do
    test[i] := char(1 + random(255));
  writeln ('Original: ', test);
  writeln ('No CNTL:  ', Strip(test, true,  false));
  writeln ('No extnd: ', Strip(test, false, true));
  writeln ('ASCII:    ', Strip(test, true,  true));
end.


Create variable with control characters: <@ SAYLETVARLIT>i|This string has control characters
	-	-	-	-	-	-

in it</@>
Strip control characters <@ SAYSALVAR>i</@>
Assign infix <@ LETVARSALVAR>j|i</@> <@ SAYVAR>j</@>
Assign prepend <@ LETSALVARVAR>k|i</@> <@ SAYVAR>k</@>
Reflexive assign <@ ACTSALVAR>i</@> <@ SAYVAR>i</@>


aList = "   Welcome to the Ring Programming Language   "
see aList + nl
see trim(aList) + nl


s = " \t\v\r\n\ffoo bar \t\v\r\n\f"
p s
p s.lstrip    # remove leading whitespaces
p s.rstrip    # remove trailing whitespaces
p s.strip     # remove both leading and trailing whitespace


string$ = "  abcdefg  "

print "   Top:";trim$(string$+"|")       ' top    left trim
print "Bottom:";trim$("|"+string$)       ' bottom right trim
print "  Both:";trim$(string$)           ' both   left and right
end


fn main() {
    let spaces = " \t\n\x0B\x0C\r \u{A0} \u{2000}\u{3000}";
    let string_with_spaces = spaces.to_owned() + "String without spaces" + spaces;

    assert_eq!(string_with_spaces.trim(), "String without spaces");
    assert_eq!(string_with_spaces.trim_left(), "String without spaces".to_owned() + spaces);
    assert_eq!(string_with_spaces.trim_right(), spaces.to_owned() + "String without spaces");
}


import strutils

proc removeComments(line: string; sep: char): string =
  line.split(sep)[0].strip(leading = false)

const
  Str1 = "apples, pears # and bananas"
  Str2 = "apples, pears ; and bananas"

echo "Original: “$#”" % Str1
echo "Stripped: “$#”" % Str1.removeComments('#')
echo "Original: “$#”" % Str2
echo "Stripped: “$#”" % Str2.removeComments(';')


use System.IO.File;

class StripComments {
  function : Main(args : String[]) ~ Nil {
    reader : FileReader;
    if(args->Size() = 1) {
      reader := FileReader->New(args[0]);
      line := reader->ReadString();
      while(line <> Nil) {
        index := line->FindLast(';');
        if(index < 0) {
          index := line->FindLast('#');
        };

        if(index > -1) {
          line->SubString(index)->PrintLine();
        };

        line := reader->ReadString();
      };
    };

    leaving {
      if(reader <> Nil) {
        reader->Close();
      };
    };
  }
}


let strip_comments str =
  let len = String.length str in
  let rec aux print i =
    if i >= len then () else
    match str.[i] with
    | '#' | ';' ->
        aux false (succ i)
    | '\n' ->
        print_char '\n';
        aux true (succ i)
    | c ->
        if print then print_char c;
        aux print (succ i)
  in
  aux true 0

let () =
  strip_comments "apples, pears # and bananas\n";
  strip_comments "apples, pears ; and bananas\n";
;;


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

my @letters ;
my @nocontrols ;
my @noextended ;
for ( 1..40 ) {
   push @letters ,  int( rand( 256 ) ) ;
}
print "before sanitation : " ;
print join( '' , map { chr( $_ ) } @letters ) ;
print "\n" ;
@nocontrols = grep { $_ > 32 && $_ != 127 } @letters ;
print "Without controls: " ;
print join( '' , map { chr( $_ ) } @nocontrols ) ;
@noextended = grep { $_ < 127 } @nocontrols ;
print "\nWithout extended: " ;
print join( '' , map { chr( $_ ) } @noextended ) ;
print "\n" ;


with javascript_semantics
requires("1.0.2") -- (param default fixes in pwa/p2js)
function filter_it(string s, integer fromch=' ', toch=#7E, abovech=#7F)
    string res = ""
    for i=1 to length(s) do
        integer ch = s[i]
        if ch>=fromch and (ch<=toch or ch>abovech) then
            res &= ch
        end if
    end for
    return res
end function

procedure put_line(string text, s)
    printf(1,"%s \"%s\", Length:%d\n",{text,s,length(s)})
end procedure

string full = "\u0000 abc\u00E9def\u007F"

put_line("The full string:", full)
put_line("No Control Chars:", filter_it(full)) -- default values for fromch, toch, and abovech
put_line("\" and no Extended:", filter_it(full, abovech:=#FF)) -- defaults for fromch and toch


class MAIN is
    ltrim(s :STR) :STR is
      i ::= 0;
      loop while!(i < s.size);
        if " \t\f\v\n".contains(s[i]) then
           i := i + 1;
        else
           break!;
        end;
      end;
      return s.tail(s.size - i);
    end;

    rtrim(s :STR) :STR is
      i ::= s.size-1;
      loop while!(i >= 0);
        if " \t\f\v\n".contains(s[i]) then
           i := i - 1;
        else
           break!;
        end;
      end;
      return s.head(i+1);
    end;

    trim(s :STR) :STR is
       return ltrim(rtrim(s));
    end;

    main is
      p ::= "     this is a string     ";
      #OUT + ltrim(p).pretty + "\n";
      #OUT + rtrim(p).pretty + "\n";
      #OUT + trim(p).pretty + "\n";
    end;
end;


def trimLeft(str: String) = str dropWhile(_.isWhitespace)

def trimRight(str: String) = str take (str.lastIndexWhere(!_.isWhitespace) + 1)

def trimRight2(str: String) = trimLeft(str reverse) reverse

def trim(str: String) = str trim

def testTrim() = {
  val str = "  \u001F  String with spaces \t  \n  \r "
  println("original  : |" + str + "|")
  println("trimLeft  : |" + trimLeft(str) + "|")
  println("trimRight : |" + trimRight(str) + "|")
  println("trimRight2: |" + trimRight2(str) + "|")
  println("trim      : |" + trim(str) + "|")
}


$ include "seed7_05.s7i";

const proc: main is func
  local
    const string: testStri is " \t \r \n String with spaces  \t  \r  \n  ";
  begin
    writeln(ltrim(testStri));
    writeln(rtrim(testStri));
    writeln(trim(testStri));
  end func;


: stripComments(s, markers)
| firstMarker |
   markers map(#[ s indexOf ]) reduce(#min) ->firstMarker
   s firstMarker ifNotNull: [ left(firstMarker 1 - ) ] strip ;


while (<>)
  {
    s/[#;].*$//s; # remove comment
    s/^\s+//;     # remove leading whitespace
    s/\s+$//;     # remove trailing whitespace
    print
  }


with javascript_semantics
function strip_comments(string s, sequence comments={"#",";"})
    for i=1 to length(comments) do
        integer k = match(comments[i],s)
        if k then
            s = s[1..k-1]
            s = trim_tail(s)
        end if
    end for
    return s
end function

?strip_comments("apples, pears # and bananas")
?strip_comments("apples, pears ; and bananas")
?strip_comments("apples, pears and bananas  ")
?strip_comments("    WS_CAPTION = #00C00000, -- = WS_BORDER+WS_DLGFRAME")
?strip_comments("    WS_CAPTION = #00C00000, -- = WS_BORDER+WS_DLGFRAME",{"--"})
?strip_comments("  title = \"--Title--\"",{"--"})


(de stripCtrl (Str)
   (pack
      (filter
         '((C)
            (nor (= "^?" C) (> " " C "^A")) )
         (chop Str) ) ) )

(de stripCtrlExt (Str)
   (pack
      (filter
         '((C) (> "^?" C "^_"))
         (chop Str) ) ) )


> string input = random_string(100);
> (string)((array)input-enumerate(32)-enumerate(255-126,1,127));
Result: "p_xx08M]cK<FHgR3\\I.x>)Tm<VgakYddy&P7"


stripper: proc options (main);
   declare s character (100) varying;
   declare i fixed binary;

   s = 'the quick brown fox jumped';
   /* A loop to replace blanks with control characters */
   do i = 1 to length(s);
      if substr(s, i, 1) = ' ' then
         substr(s, i, 1) = '01'x;
   end;
   put skip list (s);

   call stripcc (s);
   put skip list (s);

   s = 'now is the time for all good men';
   /* A loop to replace blanks with control characters */
   do i = 1 to length(s);
      if substr(s, i, 1) = ' ' then
         substr(s, i, 1) = 'A1'x;
   end;
   put skip list (s);

   call stripex (s);
   put skip list (s);

/* Strip control codes. */
stripcc: procedure (s);
   declare s character (*) varying;
   declare w character (length(s));
   declare c character (1);
   declare (i, j) fixed binary;

   j = 0;
   do i = 1 to length (s);
      c = substr(s, i, 1);
      if unspec(c) >= '00100000'b | unspec(c) = '01111111'b then
         do;
            j = j + 1;
            substr(w, j, 1) = c;
         end;
   end;
   s = substr(w, 1, j);
end stripcc;

/* Strips control codes and extended characters. */
stripex: procedure (s);
   declare s character (*) varying;
   declare w character (length(s));
   declare c character (1);
   declare (i, j) fixed binary;

   j = 0;
   do i = 1 to length (s);
      c = substr(s, i, 1);
      if unspec(c) >= '00100000'b & unspec(c) < '01111111'b then
         do;
            j = j + 1;
            substr(w, j, 1) = c;
         end;
   end;
   s = substr(w, 1, j);
end stripex;

end stripper;


function Remove-Character
{
    [CmdletBinding(DefaultParameterSetName="Control and Extended")]
    [OutputType([string])]
    Param
    (
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [string]
        $String,

        [Parameter(ParameterSetName="Control")]
        [switch]
        $Control,

        [Parameter(ParameterSetName="Extended")]
        [switch]
        $Extended
    )

    Begin
    {
        filter Remove-ControlCharacter
        {
            $_.ToCharArray() | ForEach-Object -Begin {$out = ""} -Process {if (-not [Char]::IsControl($_)) {$out += $_ }} -End {$out}
        }

        filter Remove-ExtendedCharacter
        {
            $_.ToCharArray() | ForEach-Object -Begin {$out = ""} -Process {if ([int]$_ -lt 127) {$out += $_ }} -End {$out}
        }
    }
    Process
    {
        foreach ($s in $String)
        {
            switch ($PSCmdlet.ParameterSetName)
            {
                "Control"  {$s | Remove-ControlCharacter}
                "Extended" {$s | Remove-ExtendedCharacter}
                Default    {$s | Remove-ExtendedCharacter | Remove-ControlCharacter}
            }
        }
    }
}


var s = " \t\v\r\n\ffoo bar \t\v\r\n\f";
say s.strip_beg.dump;    # remove leading whitespaces
say s.strip_end.dump;    # remove trailing whitespaces
say s.strip.dump;        # remove both leading and trailing whitespace


String extend
[
   ltrim [
      ^self replacingRegex: '^\s+' with: ''.
   ]
   rtrim [
      ^self replacingRegex: '\s+$' with: ''.
   ]
   trim [
      ^self ltrim rtrim.
   ]
]

|a|
a := '      this is a string       '.

('"%1"' % {a}) displayNl.
('"%1"' % {a ltrim}) displayNl.
('"%1"' % {a rtrim}) displayNl.
('"%1"' % {a trim}) displayNl.


    s1 = s2 = " 	Hello, people of earth!  	"
    s2 = CHAR(3) s2 CHAR(134)
    &ALPHABET TAB(33) . prechars
    &ALPHABET POS(127) RTAB(0) . postchars
    stripchars = " " prechars postchars

* TRIM() removes final spaces and tabs:
    OUTPUT = "Original: >" s1 "<"
    OUTPUT = "With trim() >" REVERSE(TRIM(REVERSE(TRIM(s1)))) "<"

* Remove all non-printing characters:
    OUTPUT = "Original: >" s2 "<"
    s1 POS(0) SPAN(stripchars) =
    OUTPUT = "Leading: >" s1 "<"
    s2 ARB . s2 SPAN(stripchars) RPOS(0)
    OUTPUT = "Trailing: >" s2 "<"
    s2 POS(0) SPAN(stripchars) =
    OUTPUT = "Full trim: >" s2 "<"
END


local
  open Substring
in
  val trimLeft = string o dropl Char.isSpace o full
  and trimRight = string o dropr Char.isSpace o full
  and trim = string o dropl Char.isSpace o dropr Char.isSpace o full
end


(for Str '("apples, pears # and bananas" "apples, pears ; and bananas")
   (prinl (car (split (chop Str) "#" ";"))) )


k = search(text, '#;');
if k = 0 then put skip list (text);
         else put skip list (substr(text, 1, k-1));


stripcomment(A,B) :- stripcomment(A,B,a).
stripcomment([A|AL],[A|BL],a) :- \+ A=0';, \+ A=0'# , \+ A=10, \+ A=13 , stripcomment(AL,BL,a).
stripcomment([A|AL],   BL ,a) :-  ( A=0';;    A=0'#), \+ A=10, \+ A=13 , stripcomment(AL,BL,b).
stripcomment([A|AL],   BL ,b) :-                      \+ A=10, \+ A=13 , stripcomment(AL,BL,b).
stripcomment([A|AL],[A|BL],_M):-                       ( A=10;    A=13), stripcomment(AL,BL,a).
stripcomment([],[],_M).
start :-
In = "apples, pears ; and bananas
apples, pears # and bananas",
    stripcomment(In,Out),
    format("~s~n",[Out]).


Procedure.s Strip_comments(Str$)
  Protected result$=Str$, l, l1, l2
  l1 =FindString(Str$,"#",1)
  l2 =FindString(Str$,";",1)
  ;
  ; See if any comment sign was found, prioritizing '#'
  If l1
    l=l1
  ElseIf l2
    l=l2
  EndIf
  l-1
  If l>0
    result$=Left(Str$,l)
  EndIf
  ProcedureReturn result$
EndProcedure


Procedure.s stripControlCodes(source.s)
  Protected i, *ptrChar.Character, length = Len(source), result.s
  *ptrChar = @source
  For i = 1 To length
    If *ptrChar\c > 31
      result + Chr(*ptrChar\c)
    EndIf
    *ptrChar + SizeOf(Character)
  Next
  ProcedureReturn result
EndProcedure

Procedure.s stripControlExtCodes(source.s)
  Protected i, *ptrChar.Character, length = Len(source), result.s
  *ptrChar = @source
  For i = 1 To length
    If *ptrChar\c > 31 And *ptrChar\c < 128
      result + Chr(*ptrChar\c)
    EndIf
    *ptrChar + SizeOf(Character)
  Next
  ProcedureReturn result
EndProcedure

If OpenConsole()
  ;create sample string
  Define i, s.s
  For i = 1 To 80
    s + Chr(Random(254) + 1) ;include character values from 1 to 255
  Next

  PrintN(stripControlCodes(s))    ;string without control codes
  PrintN("---------")
  PrintN(stripControlExtCodes(s)) ;string without control codes or extended chars

  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


stripped = lambda s: "".join(i for i in s if 31 < ord(i) < 127)

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


#lang racket
;; Works on both strings (Unicode) and byte strings (raw/ASCII)
(define (strip-controls str)
  (regexp-replace* #rx"[\0-\037\177]+" str ""))
(define (strip-controls-and-extended str)
  (regexp-replace* #rx"[^\040-\176]+" str ""))


s = "   ars   longa   "
"("+strtrim(s)+")"
  (ars   longa)

"("+strltrim(s)+")"
  (ars   longa   )

"("+strrtrim(s)+")"
  (   ars   longa)

"("+stritrim(s)+")"
  (   ars longa   )


set str "      hello world      "
puts "original: >$str<"
puts "trimmed head: >[string trimleft $str]<"
puts "trimmed tail: >[string trimright $str]<"
puts "trimmed both: >[string trim $str]<"


PROGRAM:WHITESPC
Input Str1
0→M
Menu("     REMOVE     ","TRAILIN WHTSPC",A,"LEADING WHTSPC",C,"BOTH",B)

Lbl B
1→M

Lbl A
While sub(Str1,length(Str1)-1),1)=" "
sub(Str1,1,length(Str1)-1)→Str1
End

If M=1
Then
Goto C
Else
Goto F
End

Lbl C
While sub(str1,1,1)=" "
sub(Str1,2,length(Str1)-1)→Str1
End

Lbl F
Disp "'"+Str1+"'"


 $string = "                 yep                 ";
 $string = LTrim($string);
 echo($string);


def remove_comments(line, sep):
    for s in sep:
        i = line.find(s)
        if i >= 0:
            line = line[:i]
    return line.strip()

# test
print remove_comments('apples ; pears # and bananas', ';#')
print remove_comments('apples ; pears # and bananas', '!')


strip_comments <- function(str)
{
  if(!require(stringr)) stop("you need to install the stringr package")
  str_trim(str_split_fixed(str, "#|;", 2)[, 1])
}


#lang at-exp racket

(define comment-start-rx "[;#]")

(define text
  @~a{apples, pears # and bananas
      apples, pears ; and bananas
      })

(define (strip-comments text [rx comment-start-rx])
  (string-join
   (for/list ([line (string-split text "\n")])
     (string-trim line (pregexp (~a "\\s*" rx ".*")) #:left? #f))
   "\n"))

;; Alternatively, do it in a single regexp operation
(define (strip-comments2 text [rx comment-start-rx])
  (regexp-replace* (pregexp (~a "(?m:\\s*" rx ".*)")) text ""))

(strip-comments2 text) ; -> "apples, pears\napples, pears"


>> parse s: "apples, pears ; and bananas" [to [any space ";"] remove thru end]
== true
>> s
== "apples, pears"


/*REXX program  strips  a string  delineated  by a  hash (#)   or   a  semicolon (;).   */
old1= ' apples, pears # and bananas'      ;      say '                 old ───►'old1"◄───"
new1= stripCom1(old1)                     ;      say '     1st version new ───►'new1"◄───"
new2= stripCom2(old1)                     ;      say '     2nd version new ───►'new2"◄───"
new3= stripCom3(old1)                     ;      say '     3rd version new ───►'new3"◄───"
new4= stripCom4(old1)                     ;      say '     4th version new ───►'new4"◄───"
                                                 say  copies('▒', 62)
old2= ' apples, pears ; and bananas'      ;      say '                 old ───►'old2"◄───"
new1= stripCom1(old2)                     ;      say '     1st version new ───►'new1"◄───"
new2= stripCom2(old2)                     ;      say '     2nd version new ───►'new2"◄───"
new3= stripCom3(old2)                     ;      say '     3rd version new ───►'new3"◄───"
new4= stripCom4(old2)                     ;      say '     4th version new ───►'new4"◄───"
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
stripCom1: procedure;   parse arg x              /*obtain the argument (the  X  string).*/
           x=translate(x, '#', ";")              /*translate semicolons to a hash (#).  */
           parse  var  x    x  '#'               /*parse the X string,  ending in hash. */
           return strip(x)                       /*return the stripped shortened string.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
stripCom2: procedure;   parse arg x              /*obtain the argument (the  X  string).*/
           d= ';#'                               /*this is the delimiter list to be used*/
           d1=left(d,1)                          /*get the first character in delimiter.*/
           x=translate(x,copies(d1,length(d)),d) /*translates delimiters ──►  1st delim.*/
           parse  var  x    x  (d1)              /*parse the string,  ending in a hash. */
           return strip(x)                       /*return the stripped shortened string.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
stripCom3: procedure;   parse arg x              /*obtain the argument (the  X  string).*/
           d= ';#'                               /*this is the delimiter list to be used*/
                           do j=1  for length(d) /*process each of the delimiters singly*/
                           _=substr(d,j,1)       /*use only one delimiter at a time.    */
                           parse  var  x  x  (_) /*parse the  X  string for each delim. */
                           end   /*j*/           /* [↑]    (_)  means stop parsing at _ */
           return strip(x)                       /*return the stripped shortened string.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
stripCom4: procedure;   parse arg x              /*obtain the argument (the  X  string).*/
           d= ';#'                               /*this is the delimiter list to be used*/
                    do k=1  for length(d)        /*process each of the delimiters singly*/
                    p=pos(substr(d,k,1), x)      /*see if a delimiter is in the X string*/
                    if p\==0  then x=left(x,p-1) /*shorten the X string by one character*/
                    end   /*k*/                  /* [↑]  If p==0, then char wasn't found*/
           return strip(x)                       /*return the stripped shortened string.*/


my $str = (0..400).roll(80)».chr.join;

say $str;
say $str.subst(/<:Cc>/,      '', :g); # unicode property: control character
say $str.subst(/<-[\ ..~]>/, '', :g);


/*REXX program strips all  "control codes"  from a character string  (ASCII or EBCDIC). */
z= 'string of ☺☻♥♦⌂, may include control characters and other    ♫☼§►↔◄░▒▓█┌┴┐±÷²¬└┬┘ilk.'
@=' !"#$%&''()*+,-./0123456789:;<=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
$=
   do j=1  for length(z);   _=substr(z, j, 1)    /*get a char from   X   one at a time. */
   if verify(_, @)==0  then $=$ || _             /*Is char in the @ list?   Then use it.*/
   end   /*j*/                                   /*stick a fork in it,  we're all done. */

say 'old = »»»'z"«««"                            /*add ««fence»» before & after old text*/
say 'new = »»»'$"«««"                            /* "      "        "   "   "   new   " */


s = char(31) + "abc" + char(13) + "def" + char(11) + "ghi" + char(10)
see strip(s) + nl

func strip str
strip = ""
for i = 1 to len(str)
    nr = substr(str,i,1)
    a = ascii(nr)
    if a > 31 and a < 123 and nr != "'" and nr != """"
       strip = strip + nr ok
next
return strip


class String
  def strip_control_characters()
    chars.each_with_object("") do |char, str|
      str << char unless char.ascii_only? and (char.ord < 32 or char.ord == 127)
    end
  end

  def strip_control_and_extended_characters()
    chars.each_with_object("") do |char, str|
      str << char if char.ascii_only? and char.ord.between?(32,126)
    end
  end
end

p s = "\ba\x00b\n\rc\fd\xc3\x7ffoo"
p s.strip_control_characters
p s.strip_control_and_extended_characters


$$ MODE TUSCRIPT
str= "      sentence w/whitespace before and after    "
trimmedtop=EXTRACT (str,":<|<> :"|,0)
trimmedtail=EXTRACT (str,0,":<> >|:")
trimmedboth=SQUEEZE(str)
PRINT "string           <|", str," >|"
PRINT "trimmed on top   <|",trimmedtop,">|"
PRINT "trimmed on tail  <|", trimmedtail,">|"
PRINT "trimmed on both  <|", trimmedboth,">|"


@(define trim_left (in out))
@  (next :list in)
@/[ \t]*/@out
@(end)
@(define trim_right (in out))
@  (local blanks middle)
@  (next :list in)
@  (cases)
@    {blanks /[ \t]*/}@[email protected]/[\t ]+/
@    (bind out `@[email protected]`)
@  (or)
@    out
@  (end)
@(end)
@line_of_input
@(output)
trim-left:  [@{line_of_input :filter (:fun trim_left)}]
trim_right: [@{line_of_input :filter (:fun trim_right)}]
trim_both:  [@{line_of_input :filter ((:fun trim_left) (:fun trim_right))}]
@(end)


#import std

white      = ==` !| not @iNC %sI
trim_left  = white-~r
trim_right = white~-l
trim_both  = trim_left+ trim_right

#cast %sgUL

main = <.trim_left,trim_right,trim_both> '  string with spaces   '


string s = "   word   ";
string s_chug = s.chug();


aList = 'apples, pears # and bananas'
see aList + nl
see stripComment(aList) + nl
aList = 'apples, pears // and bananas'
see aList + nl
see stripComment(aList) + nl

func stripComment bList
     nr = substr(bList,"#")
     if nr > 0 cList = substr(bList,1,nr-1) ok
     nr = substr(bList,"//")
     if nr > 0 cList = substr(bList,1,nr-1) ok
     return cList


class String
  def strip_comment( markers = ['#',';'] )
    re = Regexp.union( markers ) # construct a regular expression which will match any of the markers
    if index = (self =~ re)
      self[0, index].rstrip      # slice the string where the regular expression matches, and return it.
    else
      rstrip
    end
  end
end

p 'apples, pears # and bananas'.strip_comment
str = 'apples, pears ; and bananas'
p str.strip_comment
str = 'apples, pears and bananas '
p str.strip_comment
p str.strip_comment('and')
p " \t \n ;".strip_comment
p "".strip_comment


fn strip_comment<'a>(input: &'a str, markers: &[char]) -> &'a str {
    input
        .find(markers)
        .map(|idx| &input[..idx])
        .unwrap_or(input)
        .trim()
}

fn main() {
    println!("{:?}", strip_comment("apples, pears # and bananas", &['#', ';']));
    println!("{:?}", strip_comment("apples, pears ; and bananas", &['#', ';']));
    println!("{:?}", strip_comment("apples, pears and bananas ", &['#', ';']));
}


object StripComments {
  def stripComments1(s:String, markers:String =";#")=s takeWhile (!markers.contains(_)) trim

  // using regex and pattern matching
  def stripComments2(s:String, markers:String =";#")={
    val R=("(.*?)[" + markers + "].*").r
    (s match {
      case R(line) => line
      case _ => s
    }) trim
  }

  def print(s:String)={
    println("'"+s+"' =>")
    println("   '"+stripComments1(s)+"'")
    println("   '"+stripComments2(s)+"'")
  }

  def main(args: Array[String]): Unit = {
    print("apples, pears # and bananas")
    print("apples, pears ; and bananas")
  }
}


val controlCode : (Char) => Boolean = (c:Char) => (c <= 32 || c == 127)
val extendedCode : (Char) => Boolean = (c:Char) => (c <= 32 || c > 127)

// ASCII test...
val teststring = scala.util.Random.shuffle( (1.toChar to 254.toChar).toList ).mkString

println( "ctrl filtered out: \n\n" +
  teststring.filterNot(controlCode) + "\n" )

println( "ctrl and extended filtered out: \n\n" +
  teststring.filterNot(controlCode).filterNot(extendedCode) + "\n" )


$ include "seed7_05.s7i";
  include "utf8.s7i";

const func string: stripControl (in string: stri) is func
  result
    var string: stripped is "";
  local
    var integer: old_pos is 1;
    var integer: index is 0;
    var char: ch is ' ';
  begin
    for ch key index range stri do
      if ch < ' ' or ch = '\127;' then
        stripped &:= stri[old_pos .. pred(index)];
        old_pos := succ(index);
      end if;
    end for;
    stripped &:= stri[old_pos ..];
  end func;

const func string: stripControlAndExtended (in string: stri) is func
  result
    var string: stripped is "";
  local
    var integer: old_pos is 1;
    var integer: index is 0;
    var char: ch is ' ';
  begin
    for ch key index range stri do
      if ch < ' ' or ch >= '\127;' then
        stripped &:= stri[old_pos .. pred(index)];
        old_pos := succ(index);
      end if;
    end for;
    stripped &:= stri[old_pos ..];
  end func;

const string: src is "déjà vu\              # Unicode
    \\n\0;\31; \33;\126;\127;\128;\255;\n\  # Various boundary cases
    \as⃝df̅";                                 # Unicode combining characters

const proc: main is func
  begin
    OUT := STD_UTF8_OUT;
    writeln("source text:");
    writeln(src);
    writeln("Stripped of control codes:");
    writeln(stripControl(src));
    writeln("Stripped of control codes and extended characters:");
    writeln(stripControlAndExtended(src));
  end func;


var str = "\ba\x00b\n\rc\fd\xc3\x7ffoo"

var letters = str.chars.map{.ord}
say letters.map{.chr}.join.dump

var nocontrols = letters.grep{ (_ > 32) && (_ != 127) }
say nocontrols.map{.chr}.join.dump

var noextended = nocontrols.grep{ _ < 127 }
say noextended.map{.chr}.join.dump


Public Sub test()
    'LTrim trims leading spaces
    'RTrim trims tailing spaces
    'Trim trims both leading and tailing spaces
    s = " trim "
    Debug.Print """" & s & """"
    Debug.Print """" & LTrim(s) & """"
    Debug.Print """" & RTrim(s) & """"
    Debug.Print """" & WorksheetFunction.trim(s) & """"
    'these functions do not remove tabs or newlines
End Sub


Function LeftTrim(s)
	Set regex = New RegExp
	With regex
		.Pattern = "^\s*"
		If .Test(s) Then
			LeftTrim = .Replace(s,"")
		Else
			LeftTrim = s
		End If
	End With
End Function

Function RightTrim(s)
	Set regex = New RegExp
	With regex
		.Pattern = "\s*$"
		If .Test(s) Then
			RightTrim = .Replace(s,"")
		Else
			RightTrim = s
		End If
	End With
End Function

'testing the functions
WScript.StdOut.WriteLine LeftTrim("			   RosettaCode")
WScript.StdOut.WriteLine RightTrim("RosettaCode			  		")
WScript.StdOut.WriteLine LeftTrim(RightTrim("  	RosettaCode			  		"))


var a = " \t\r\nString with leading whitespace removed"
var b = "String with trailing whitespace removed \t\r\n"
var c = " \t\r\nString with both leading and trailing whitespace removed \t\r\n"
var d = " \t\r\n\f\vString with leading whitespace, form feed and verical tab characters removed"
System.print("'%(a.trimStart())'")
System.print("'%(b.trimEnd())'")
System.print("'%(c.trim())'")
System.print("'%(d.trimStart(" \t\r\n\f\v"))'") // similar overloads of trimEnd and trim exist


(use-modules (ice-9 regex))

(define (strip-comments s)
    (regexp-substitute #f
        (string-match "[ \t\r\n\v\f]*[#;].*" s) 'pre "" 'post))

(display (strip-comments "apples, pears # and bananas"))(newline)
(display (strip-comments "apples, pears ; and bananas"))(newline)


#!/bin/sh
# Strip comments
echo "$1" | sed 's/ *[#;].*$//g' | sed 's/^ *//'


$ include "seed7_05.s7i";

const func string: stripComment (in string: line) is func
  result
    var string: lineWithoutComment is "";
  local
    var integer: lineEnd is 0;
    var integer: pos is 0;
  begin
    lineEnd := length(line);
    for pos range 1 to length(line) do
      if line[pos] in {'#', ';'} then
        lineEnd := pred(pos);
        pos := length(line);
      end if;
    end for;
    lineWithoutComment := line[.. lineEnd];
  end func;

const proc: main is func
  local
    var string: stri is "apples, pears # and bananas\n\
                        \apples, pears ; and bananas";
    var string: line is ""
  begin
    writeln(stri);
    writeln("====>");
    for line range split(stri, '\n') do
      writeln(stripComment(line));
    end for;
  end func;


func strip_comment(s) {
    (s - %r'[#;].*').strip;
}

[" apples, pears # and bananas",
 " apples, pears ; and bananas",
 " apples, pears "].each { |s|
    say strip_comment(s).dump;
};


val stripComment =
  let
    val notMarker = fn #"#" => false | #";" => false | _ => true
    open Substring
  in
    string o dropr Char.isSpace o takel notMarker o full
  end


proc stripLineComments {inputString {commentChars ";#"}} {
    # Switch the RE engine into line-respecting mode instead of the default whole-string mode
    regsub -all -line "\[$commentChars\].*$" $inputString "" commentStripped
    # Now strip the whitespace
    regsub -all -line {^[ \t\r]*(.*\S)?[ \t\r]*$} $commentStripped {\1}
}


(* string -> string *)
val stripCntrl = concat o String.tokens Char.isCntrl

(* string -> string *)
val stripCntrlAndExt = concat o String.tokens (not o Char.isPrint)


proc stripAsciiCC str {
    regsub -all {[\u0000-\u001f\u007f]+} $str ""
}
proc stripCC str {
    regsub -all {[^\u0020-\u007e]+} $str ""
}


(defun strip-controls (str)
 (regsub #/[\x0-\x1F\x7F]+/ "" str))

(defun strip-controls-and-extended (str)
  (regsub #/[^\x20-\x7F]+/ "" str))


Function StripCtrlCodes(s)
	tmp = ""
	For i = 1 To Len(s)
		n = Asc(Mid(s,i,1))
		If (n >= 32 And n <= 126) Or n >=128 Then
			tmp = tmp & Mid(s,i,1)
		End If
	Next
	StripCtrlCodes = tmp
End Function

Function StripCtrlCodesExtChrs(s)
	tmp = ""
	For i = 1 To Len(s)
		n = Asc(Mid(s,i,1))
		If n >= 32 And n <= 126 Then
			tmp = tmp & Mid(s,i,1)
		End If
	Next
	StripCtrlCodesExtChrs = tmp
End Function

WScript.StdOut.Write "ab�cd�ef�gh�€" & " = " & StripCtrlCodes("ab�cd�ef�gh�€")
WScript.StdOut.WriteLine
WScript.StdOut.Write "ab�cd�ef�gh�ij†klð€" & " = " & StripCtrlCodesExtChrs("ab�cd�ef�gh�ij†klð€")
WScript.StdOut.WriteLine


code ChOut=8, CrLf=9, Text=12;
string 0;                       \use zero-terminated string convention

func StripLead(S0);             \Strip leading whitespace (<=$20) from string
char S0;
char S1(80);                    \BEWARE: very temporary string space returned
int  I, J, C, Stripped;
[I:= 0;  J:= 0;  Stripped:= false;
repeat  C:= S0(I);  I:= I+1;
        if Stripped ! C>$20 ! C=0 then
            [S1(J):= C;  J:= J+1;  Stripped:= true];
until   C=0;
return S1;
];

func StripTrail(S0);            \Strip trailing whitespace (<=$20) from string
char S0;
char S1(80);                    \BEWARE: very temporary string space returned
int  I, SI;
[I:= 0;
loop    [if S0(I) <= $20 then
             [SI:= I;
             while S0(I) <= $20 do
                [if S0(I) = 0 then [S1(SI):= 0;  return S1];
                S1(I):= S0(I);  I:= I+1;
                ];
             ]
        else [S1(I):= S0(I);  I:= I+1];
        ];
];

char String;
[String:= "  Hello World  ";
Text(0, StripLead(String));  ChOut(0, ^!);  CrLf(0);
Text(0, StripTrail(String));  ChOut(0, ^!);  CrLf(0);
Text(0, StripTrail(StripLead(String)));  ChOut(0, ^!);  CrLf(0);
]


program: trim_left
  input: '  abcd'
  output: 'abcd'

program: trim_right
  input: 'abcd  '
  output: 'abcd'

program: trim
  input: '  abcd  '
  output: 'abcd'


$$ MODE TUSCRIPT
strngcomment=*
DATA apples, pears # and bananas
DATA apples, pears ; and bananas

BUILD S_TABLE comment_char="|#|;|"

LOOP s=strngcomment
x=SPLIT (s,comment_char,string,comment)
PRINT string
ENDLOOP


bash$ a='apples, pears ; and bananas'
bash$ b='apples, pears # and bananas'
bash$ echo ${a%%;*}
apples, pears
bash$ echo ${b%%#*}
apples, pears
bash$


Function strip_comments(s,char)
	If InStr(1,s,char) > 0 Then
		arr = Split(s,char)
		strip_comments = RTrim(arr(0))
	Else
		strip_comments = s
	End If
End Function

WScript.StdOut.WriteLine strip_comments("apples, pears # and bananas","#")
WScript.StdOut.WriteLine strip_comments("apples, pears ; and bananas",";")


var markers = ["#", ";"]

var stripComments = Fn.new { |s|
   for (marker in markers) {
       var t = s.split(marker)
       if (t.count > 1) return t[0].trim()
   }
   return s.trim()
}

var strings = [
    " apples, pears # and bananas",
    " apples, pears ; and bananas",
    " apples, pears \t     "
]

for (s in strings) {
    var t = stripComments.call(s)
    System.print("'%(s)' -> '%(t)'")
}


Proc Min
   Declare int PC, i, float e, t
   PC = %PCount
   e = @!(1)
   If PC > 1
     For i, 2, PC
       t = @!(i)
       e = if( (e == 0.0) and (t == 0.0), -(-e - t), if(t < e, t, e) )
     EndFor
   EndIf
   Return e
EndProc

Proc Odd
   Parameters int n
   Return TestBit(n,0)
EndProc

Proc strip_comments
   Parameters string s, delim
   Declare int posi[]
   Declare int i, min_p, p
   min_p = $7FFFFFFF
   For i, 1, Len(delim)
      posi[ i ] = InStr( mid$(delim,i,1), s )
      Case posi[ i ] > 0 : min_p = Min( posi[ i ], min_p )
   EndFor
   posi[ 0 ] = InStr( chr$(34), s )

   // if there is a string delimiter on the left side...
   If (posi[0] > 0) and (posi[0] < min_p)
      // ...and counting of delimiter is odd, then the sign is part of a string
      If Odd( Len( Left$(s,min_p) ) - Len( translate$( Left$(s,min_p), Chr$(34), "" )) )
         p = posi[ 0 ] + 1
         min_p = $7FFFFFFF
         Repeat
            // closing quote
            posi[ 0 ] = InStr( chr$(34), s, p )
            'Case posi[0] > 0 : posi[0] = posi[0] + p
            p = posi[ 0 ] + 1

            // find new positions after that
            For i, 1, Len(delim)
               posi[ i ] = InStr( mid$(delim,i,1), s, p )
               Case posi[ i ] > 0 : min_p = Min( posi[ i ], min_p )
            EndFor
            posi[ 0 ] = InStr( chr$(34), s, p )

            // if there is a string delimiter on the left side...
            If (posi[0] > 0) and (posi[0] < min_p)
               // ...and counting of delimiter is odd, then the sign is part of a string
               If Odd( Len( Left$(s,min_p) ) - Len( translate$( Left$(s,min_p), Chr$(34), "" )) )
                  p = posi[ 0 ] + 1
                  min_p = $7FFFFFFF
                  // and again....
                  CONTINUE
               EndIf
            EndIf
            BREAK
         Until min_p = 0
      EndIf
   EndIf
   Return Trim$( Left$( s, min_p - 1 ) )
EndProc

cls
declare string s, t

s = " apples, pears # and bananas"
t = strip_comments( s, "#;" )
Print s + "|\n-> [" + t + "]\n"

s = " apples, pears ; and bananas"
t = strip_comments( s, "#;" )
Print s + "|\n-> [" + t + "]\n"

s = " apples, pears \t     "
t = strip_comments( s, "#;" )
Print s + "|\n-> [" + t + "]\n"

s = " " + chr$(34) + " #oh, my god " + chr$(34) + " apples, pears # and bananas"
t = strip_comments( s, "#;" )
Print s + "|\n-> [" + t + "]\n"

waitkey
end


import "/pattern" for Pattern

var s = "\t\n\r\x01\0\fabc\v\v\b\a\x1f\x7f🌇Páez😃É"

// strip control codes only
var p = Pattern.new("+1/c")
var r = p.replaceAll(s, "")
System.print("%(r) -> length %(r.count)")

// strip extended characters as well
p = Pattern.new("[+1/c|+1/R]")
r = p.replaceAll(s, "")
System.print("%(r) -> length %(r.count)")


include c:\cxpl\codes;          \intrinsic 'code' declarations
string 0;                       \use zero-terminated string convention

proc Strip(Str, Both);          \Strip out control and optionally extended chars
char Str; int Both;
int  I, J, C;
[I:= 0;
while Str(I) do
    [C:= Str(I);
    if Both then C:= extend(C); \if stripping extended chars too, extend sign
    if C<$20 or C=$7F then
        [J:= I;                 \eliminate char by shifting string down over it
        repeat  C:= Str(J+1);
                Str(J):= C;
                J:= J+1;
        until   C=0;
        ]
    else I:= I+1;
    ];
];

char String;
[String:= "Hello^M^J World àáâã";
Text(0, String);  CrLf(0);
Strip(String, false);
Text(0, String);  CrLf(0);
Strip(String, true);
Text(0, String);  CrLf(0);
]


var ctlCodes=([1..31].pump(String,"toChar") +(127).toChar());
var extdChars=[127..255].pump(String,"toChar");

var test = "string of ☺☻♥♦⌂, control characters(\t\b\e) and other ilk.♫☼§►↔◄";
test.println("<< test string");
(test-ctlCodes).println("<< no control chars");
(test-extdChars).println("<< no extended chars");
(test-extdChars-ctlCodes).println("<< text");


fcn strip(text,c){  // if c in text, remove it and following text
   if (Void!=(n:=text.find(c))) text=text[0,n];
   text.strip()		// remove leading and trailing white space
}
fcn stripper(text,a,b,c,etc){ // strip a,b,c,etc from text
   foreach c in (vm.arglist[1,*]){ text=strip(text,c) }
   text
}


*        String prepend - 14/04/2020
PREPEND  CSECT
         USING  PREPEND,13         base register
         B      72(15)             skip savearea
         DC     17F'0'             savearea
         SAVE   (14,12)            save previous context
         ST     13,4(15)           link backward
         ST     15,8(13)           link forward
         LR     13,15              set addressability
         MVC    C+L'B(L'A),A       c=a
         MVC    C(L'B),B           c=b+c  (prepend)
         XPRNT  C,L'C              print buffer
         L      13,4(0,13)         restore previous savearea pointer
         RETURN (14,12),RC=0       restore registers from calling sav
A        DC     C'world!'          a
B        DC     C'Hello '          b
C        DC     CL80' '            c
         END    PREPEND


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program appendstr64.s   */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"

/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szMessString:            .asciz "British Museum.\n"
szComplement:            .skip 80
szStringStart:           .asciz "The rosetta stone is at "
szCarriageReturn:        .asciz "\n"
/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss
/*******************************************/
/*  code section                           */
/*******************************************/
.text
.global main
main:

    ldr x0,qAdrszMessString               // display message
    bl affichageMess

    ldr x0,qAdrszMessString
    ldr x1,qAdrszStringStart
    bl prepend                             // append sting2 to string1
    ldr x0,qAdrszMessString
    bl affichageMess

    ldr x0,qAdrszCarriageReturn
    bl affichageMess

100:                                      // standard end of the program
    mov x0,0                              // return code
    mov x8,EXIT                           // request to exit program
    svc 0                                 // perform system call
qAdrszMessString:         .quad szMessString
qAdrszStringStart:        .quad szStringStart
qAdrszCarriageReturn:     .quad szCarriageReturn
/**************************************************/
/*     append two strings                         */
/**************************************************/
/* x0 contains the address of the string1 */
/* x1 contains the address of the string2 */
prepend:
    stp x1,lr,[sp,-16]!            // save  registers
    mov x3,#0                                // length counter
1:                                           // compute length of string 1
    ldrb w4,[x0,x3]
    cmp w4,#0
    cinc  x3,x3,ne                           // increment to one if not equal
    bne 1b                                   // loop if not equal
    mov x5,#0                                // length counter insertion string
2:                                           // compute length of insertion string
    ldrb w4,[x1,x5]
    cmp x4,#0
    cinc  x5,x5,ne                           // increment to one if not equal
    bne 2b
    cmp x5,#0
    beq 99f                                  // string empty -> error
    add x3,x3,x5                             // add 2 length
    add x3,x3,#1                             // +1 for final zero
    mov x6,x0                                // save address string 1
    mov x0,#0                                // allocation place heap
    mov x8,BRK                               // call system 'brk'
    svc #0
    mov x5,x0                                // save address heap for output string
    add x0,x0,x3                             // reservation place x3 length
    mov x8,BRK                               // call system 'brk'
    svc #0
    cmp x0,#-1                               // allocation error
    beq 99f
    mov x4,#0                      // counter byte string 2
3:
    ldrb w3,[x1,x4]                // load byte string 2
    cbz x3,4f                      // zero final ?
    strb w3,[x5,x4]                // store byte string 2 in heap
    add x4,x4,1                    // increment counter 1
    b 3b                           // no -> loop
4:
    mov x2,#0                      // counter byte string 1
5:
    ldrb w3,[x6,x2]                // load byte string 1
    strb w3,[x5,x4]                // store byte string in heap
    cbz x3,6f                    // zero final ?
    add x2,x2,1                    // no -> increment counter 1
    add x4,x4,1                    // no -> increment counter 2
    b 5b                           // no -> loop
6:                                 // recopie heap in string 1
    mov x2,#0                      // counter byte string
7:
    ldrb w3,[x5,x2]                // load byte string in heap
    strb w3,[x6,x2]                // store byte string 1
    cbz x3,100f                    // zero final ?
    add x2,x2,1                    // no -> increment counter 1
    b 7b                           // no -> loop
100:

    ldp x1,lr,[sp],16              // restaur  2 registers
    ret                            // return to address lr x30
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


PROC Append(CHAR ARRAY text,suffix)
  BYTE POINTER srcPtr,dstPtr
  BYTE len

  len=suffix(0)
  IF text(0)+len>255 THEN
    len=255-text(0)
  FI
  IF len THEN
    srcPtr=suffix+1
    dstPtr=text+text(0)+1
    MoveBlock(dstPtr,srcPtr,len)
    text(0)==+suffix(0)
  FI
RETURN

PROC Prepend(CHAR ARRAY text,prefix)
  CHAR ARRAY tmp(256)

  SCopy(tmp,text)
  SCopy(text,prefix)
  Append(text,tmp)
RETURN

PROC TestPrepend(CHAR ARRAY text,preffix)
  PrintF("Source ""%S"" at address %H%E",text,text)
  PrintF("Prepend ""%S""%E",preffix)
  Prepend(text,preffix)
  PrintF("Result ""%S"" at address %H%E",text,text)
  PutE()
RETURN

PROC Main()
  CHAR ARRAY text(256)

  text(0)=0
  TestPrepend(text,"World!")
  TestPrepend(text,"Hello ")
RETURN


with Ada.Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

procedure Prepend_String is
   S: Unbounded_String := To_Unbounded_String("World!");
begin
   S := "Hello " & S;-- this is the operation to prepend "Hello " to S.
   Ada.Text_IO.Put_Line(To_String(S));
end Prepend_String;


#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #

STRING str := "12345678";
"0" +=: str;
print(str)


set aVariable to "world!"
set aVariable to "Hello " & aVariable
return aVariable


a: "World"
a: "Hello" ++ a
print a

b: "World"
b: append "Hello" b
print a

c: "World"
prefix 'c "Hello"
print c

d: "World"
print prefix d "Hello"


string s1 = " World!";
write("Hello" + s1);
write("Hello", s1);
string s2 = "Hello" + s1;
write(s2);


# syntax: GAWK -f STRING_PREPEND.AWK
BEGIN {
    s = "bar"
    s = "foo" s
    print(s)
    exit(0)
}


s$ = "prepend"
s$ = "String " & s$
PRINT s$


S$ = " World!"
S$ = "Hello" + S$
PRINT S$


  World!:?string
& str$("Hello " !string):?string
& out$!string


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

int main()
{
    char str[100]="my String";
    char *cstr="Changed ";
    char *dup;
    sprintf(str,"%s%s",cstr,(dup=strdup(str)));
    free(dup);
    printf("%s\n",str);
    return 0;
}


using System;

namespace PrependString
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "World";
            str = "Hello " + str;
            Console.WriteLine(str);
            Console.ReadKey();
        }
    }
}


include <vector>
#include <algorithm>
#include <string>
#include <iostream>

int main( ) {
   std::vector<std::string> myStrings { "prepended to" , "my string" } ;
   std::string prepended = std::accumulate( myStrings.begin( ) ,
	 myStrings.end( ) , std::string( "" ) , []( std::string a ,
	    std::string b ) { return a + b ; } ) ;
   std::cout << prepended << std::endl ;
   return 0 ;
}


(defn str-prepend [a-string, to-prepend]
  (str to-prepend a-string))


       identification division.
       program-id. prepend.
       data division.
       working-storage section.
       1 str pic x(30) value "World!".
       1 binary.
        2 len pic 9(4) value 0.
        2 scratch pic 9(4) value 0.
       procedure division.
       begin.
           perform rev-sub-str
           move function reverse ("Hello ") to str (len + 1:)
           perform rev-sub-str
           display str
           stop run
           .

       rev-sub-str.
           move 0 to len scratch
           inspect function reverse (str)
           tallying scratch for leading spaces
               len for characters after space
           move function reverse (str (1:len)) to str
           .
       end program prepend.


<cfoutput>
	<cfset who = "World!">
	#"Hello " & who#
</cfoutput>


(defmacro prependf (s &rest strs)
  "Prepend the given string variable with additional strings. The string variable is modified in-place."
  `(setf ,s (concatenate 'string ,@strs ,s)))

(defvar *str* "foo")
(prependf *str* "bar")
(format T "~a~%" *str*)