Strip whitespace from a string/Top and tail
You are encouraged to solve this task according to the task description, using any language you may know.
The task is to demonstrate how to strip leading and trailing whitespace from a string. The solution should demonstrate how to achieve the following three results:
- String with leading whitespace removed
- String with trailing whitespace removed
- String with both leading and trailing whitespace removed
For the purposes of this task whitespace includes non printable characters such as the space character, the tab character, and other such characters that have no corresponding graphical representation.
Ada
<lang Ada>with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings; use Ada.Strings; with Ada.Strings.Fixed; use Ada.Strings.Fixed; procedure StripDemo is
str : String := " Jabberwocky ";
begin
Put_Line ("'" & Trim (str, Left) & "'"); Put_Line ("'" & Trim (str, Right) & "'"); Put_Line ("'" & Trim (str, Both) & "'");
end StripDemo;</lang>
- Output:
'Jabberwocky ' ' Jabberwocky' 'Jabberwocky'
AutoHotkey
AutoHotkey_L and v2 contain a Trim function <lang AutoHotkey>string := " abc " MsgBox % clipboard := "<" LTrim(string) ">`n<" RTrim(string) ">`n<" . Trim(string) ">"</lang>
- Output:
<abc > < abc> <abc>
AWK
<lang awk>#!/usr/bin/awk -f function trim(str) {
sub(/^[ \t]+/,"",str); # remove leading whitespaces sub(/[ \t]+$/,"",str); # remove trailing whitespaces return str;
} {
print trim($0);
}</lang>
BASIC
<lang qbasic> mystring$=ltrim(mystring$) ' remove leading whitespace
mystring$=rtrim(mystring$) ' remove trailing whitespace mystring$=ltrim(rtrim(mystring$)) ' remove both leading and trailing whitespace</lang>
Bracmat
Greedy pattern matching is not Bracmat's strongest field. So instead of a pattern that globs all white space characters, we have a pattern that finds the first non-whitespace character. That character, and the remainder of the subject string, constitute a left trimmed string. To do a right trim, we reverse the string, do a left trim and reverse back. <lang bracmat>( ( ltrim
= s . @( !arg : ? ( ( %@ : ~( " " | \a | \b | \n | \r | \t | \v ) ) ? : ?s ) ) & !s )
& (rtrim=.rev$(ltrim$(rev$!arg))) & (trim=.rev$(ltrim$(rev$(ltrim$!arg)))) & (string=" \a Hear the sound? \v
\r ") & out$(str$("Input:[" !string "]")) & out$(str$("ltrim:[" ltrim$!string "]")) & out$(str$("rtrim:[" rtrim$!string "]")) & out$(str$("trim :[" trim$!string "]")) & );</lang> Output (Notice the effect of the ancient \a (alarm) and \v (vertical tab)):
Input:[ Hear the sound? ♂ ] ltrim:[Hear the sound? ♂ ] rtrim:[ Hear the sound?] trim :[Hear the sound?]
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
- include <ctype.h>
char *rtrim(const char *s) {
while( isspace(*s) || !isprint(*s) ) ++s; return strdup(s);
}
char *ltrim(const char *s) {
char *r = strdup(s); if (r != NULL) { char *fr = r + strlen(s) - 1; while( (isspace(*fr) || !isprint(*fr) || *fr == 0) && fr >= r) --fr; *++fr = 0; } return r;
}
char *trim(const char *s) {
char *r = rtrim(s); char *f = ltrim(r); free(r); return f;
}
const char *a = " this is a string ";
int main() {
char *b = rtrim(a); char *c = ltrim(a); char *d = trim(a);
printf("'%s'\n'%s'\n'%s'\n", b, c, d); free(b); free(c); free(d); return 0;
}</lang>
C++
<lang cpp>#include <boost/algorithm/string.hpp>
- include <string>
- include <iostream>
int main( ) {
std::string testphrase( " There are unwanted blanks here! " ) ; std::string lefttrimmed = boost::trim_left_copy( testphrase ) ; std::string righttrimmed = boost::trim_right_copy( testphrase ) ; std::cout << "The test phrase is :" << testphrase << "\n" ; std::cout << "Trimmed on the left side :" << lefttrimmed << "\n" ; std::cout << "Trimmed on the right side :" << righttrimmed << "\n" ; boost::trim( testphrase ) ; std::cout << "Trimmed on both sides :" << testphrase << "\n" ; return 0 ;
}</lang>
- Output:
The test phrase is : There are unwanted blanks here! Trimmed on the left side :There are unwanted blanks here! Trimmed on the right side : There are unwanted blanks here! Trimmed on both sides :There are unwanted blanks here!
C#
<lang csharp>using System;
public class TrimExample {
public static void Main(String[] args) { const string toTrim = " Trim me "; Console.WriteLine(Wrap(toTrim.TrimStart())); Console.WriteLine(Wrap(toTrim.TrimEnd())); Console.WriteLine(Wrap(toTrim.Trim())); }
private static string Wrap(string s) { return "'" + s + "'"; }
}</lang>
- Output:
'Trim me ' ' Trim me' 'Trim me'
D
<lang d>import std.stdio, std.string;
void main() {
auto s = " \t \r \n String with spaces \t \r \n "; assert(s.stripLeft() == "String with spaces \t \r \n "); assert(s.stripRight() == " \t \r \n String with spaces"); assert(s.strip() == "String with spaces");
}</lang>
Delphi /Pascal
<lang Delphi>program StripWhitespace;
{$APPTYPE CONSOLE}
uses SysUtils;
const
TEST_STRING = ' String with spaces ';
begin
Writeln('"' + TEST_STRING + '"'); Writeln('"' + TrimLeft(TEST_STRING) + '"'); Writeln('"' + TrimRight(TEST_STRING) + '"'); Writeln('"' + Trim(TEST_STRING) + '"');
end.</lang>
DWScript
<lang Delphi>const TEST_STRING = ' String with spaces ';
PrintLn('"' + TEST_STRING + '"'); PrintLn('"' + TrimLeft(TEST_STRING) + '"'); PrintLn('"' + TrimRight(TEST_STRING) + '"'); PrintLn('"' + Trim(TEST_STRING) + '"');</lang>
Euphoria
A string (sequence) 'A B C' is surrounded by unwanted characters including spaces. The trim() function Trims "all items in the supplied set from both the left end (head/start) and right end (tail/end) of a sequence." It's part of the standard library, std/text.e .
Special characters in a string literal are typed 'escaped' with a '\' followed by one character. Other special characters are written using escaped hexadecimal , example : \x04 to represent hexadecimal ascii 04 or \u2A7C for 4-digit UTF, or more than two digit ascii characters : \u0127.
<lang euphoria>include std/console.e include std/text.e
sequence removables = " \t\n\r\x05\u0234\" " sequence extraSeq = " \x05\r \" A B C \n \t\t \u0234 \r\r \x05 "
extraSeq = trim(extraSeq,removables) --the work is done by the trim function
--only output programming next : printf(1, "String Trimmed is now: %s \r\n", {extraSeq} ) --print the resulting string to screen
for i = 1 to length(extraSeq) do --loop over each character in the sequence.
printf(1, "String element %d", i) --to look at more detail, printf(1, " : %d\r\n", extraSeq[i])--print integer values(ascii) of the string.
end for
any_key()</lang>
Output:
String Trimmed is now: A B C String element 1 : 65 String element 2 : 32 String element 3 : 32 String element 4 : 66 String element 5 : 32 String element 6 : 32 String element 7 : 67 Press Any Key to continue...
Forth
<lang forth>: -leading ( addr len -- addr' len' )
begin over c@ bl = while 1 /string repeat ;
\ -trailing is built in
s" test " 2dup -leading cr type 2dup -trailing cr type
-leading -trailing cr type</lang>
Go
<lang go>package main
import (
"fmt" "strings" "unicode"
)
var simple = `
simple `
func main() {
show("original", simple) show("leading ws removed", strings.TrimLeftFunc(simple, unicode.IsSpace)) show("trailing ws removed", strings.TrimRightFunc(simple, unicode.IsSpace)) // equivalent to strings.TrimFunc(simple, unicode.IsSpace) show("both removed", strings.TrimSpace(simple))
}
func show(label, str string) {
fmt.Printf("%s: |%s| %v\n", label, str, []rune(str))
}</lang> Example text is shows a leading linefeed and tab, and three trailing spaces. The code uses the Unicode definition of whitespace. Other defintions could be implemented with a custom function given to TrimXFunc.
Output below shows the text surrounded by vertical bars to show the extent of whitespace, followed by a list of the character values in the string, to show exactly what whitespace is present.
original: | simple | [10 9 115 105 109 112 108 101 32 32 32] leading ws removed: |simple | [115 105 109 112 108 101 32 32 32] trailing ws removed: | simple| [10 9 115 105 109 112 108 101] both removed: |simple| [115 105 109 112 108 101]
Groovy
Solution uses StringUtils class from Apache Commons "Lang" library: <lang groovy>//Grape setup to get library @Grab('org.apache.commons:commons-lang3:3.0.1') import static org.apache.commons.lang3.StringUtils.*
def abc = '\r\n\t abc \r\n\t'
def printTest = {
println ('|' + it + '|')
}
println 'Unstripped\n------------' printTest abc
println '============\n\nStripped\n------------' printTest strip(abc)
println '============\n\nLeft Stripped\n------------' printTest stripStart(abc, null)
println '============\n\nRight Stripped\n------------' printTest stripEnd(abc, null) println '============'</lang>
- Output:
Unstripped ------------ | abc | ============ Stripped ------------ |abc| ============ Left Stripped ------------ |abc | ============ Right Stripped ------------ | abc| ============
Haskell
<lang haskell>import Data.Char
trimLeft :: String -> String trimLeft = dropWhile isSpace
trimRight :: String -> String trimRight str | all isSpace str = "" trimRight (c : cs) = c : trimRight cs
trim :: String -> String trim = trimLeft . trimRight</lang>
Icon and Unicon
This solution takes the phrase "other such characters that have no corresponding graphical representation" quite literallly. <lang Unicon>procedure main()
unp := &cset[1+:32]++' \t'++&cset[127:0] # all 'unprintable' chars s := " Hello, people of earth! " write("Original: '",s,"'") write("leading trim: '",reverse(trim(reverse(s),unp)),"'") write("trailing trim: '",trim(s,unp),"'") write("full trim: '",reverse(trim(reverse(trim(s,unp)),unp)),"'")
end</lang>
- Sample run:
->trim Original: ' Hello, people of earth! ' leading trim: 'Hello, people of earth! ' trailing trim: ' Hello, people of earth!' full trim: 'Hello, people of earth!' ->
J
Note: The quote
verb is only used to enclose the resulting string in single quotes so the beginning and end of the new string are visible.
<lang j> require 'strings' NB. the strings library is automatically loaded in versions from J7 on
quote dlb ' String with spaces ' NB. delete leading blanks
'String with spaces '
quote dtb ' String with spaces ' NB. delete trailing blanks
' String with spaces'
quote dltb ' String with spaces ' NB. delete leading and trailing blanks
'String with spaces'</lang>
In addition deb
(delete extraneous blanks) will trim both leading and trailing blanks as well as replace consecutive spaces within the string with a single space.
<lang j> quote deb ' String with spaces ' NB. delete extraneous blanks
'String with spaces'</lang>
These existing definitions can be easily amended to include whitespace other than spaces if desired.
<lang j>whpsc=: ' ',TAB NB. define whitespace as desired
dlws=: }.~ (e.&whpsc i. 0:) NB. delete leading whitespace (spaces and tabs)
dtws=: #~ ([: +./\. -.@:e.&whpsc) NB. delete trailing whitespace
dltws=: #~ ([: (+./\ *. +./\.) -.@:e.&whpsc) NB. delete leading & trailing whitespace
dews=: #~ (+. (1: |. (> </\)))@(-.@:e.&whpsc) NB. delete extraneous whitespace</lang>
Java
Left trim and right trim taken from here.
Character.isWhitespace()
returns true if the character given is one of the following Unicode characters: '\u00A0', '\u2007', '\u202F', '\u0009', '\u000A', '\u000B', '\u000C', '\u000D', '\u001C', '\u001D', '\u001E', or '\u001F'.
<lang java>
public class Trims{
public static String ltrim(String s){ int i = 0; while (i < s.length() && Character.isWhitespace(s.charAt(i))){ i++; } return s.substring(i); }
public static String rtrim(String s){ int i = s.length() - 1; while (i > 0 && Character.isWhitespace(s.charAt(i))){ i--; } return s.substring(0, i + 1); }
public static void main(String[] args){ String s = " \t \r \n String with spaces \t \r \n "; System.out.println(ltrim(s)); System.out.println(rtrim(s)); System.out.println(s.trim()); //trims both ends }
}</lang>
Liberty BASIC
For the case of ASCII spaces, we have a trim$() function. <lang lb>sentence$ =" LeftLeadingSpaces" print trim$( sentence$) sentence$ ="RightTrailingSpaces " print trim$( sentence$) sentence$ =" Spaces left and right " print trim$( sentence$)</lang> To cover all non-printable characters, use the control-code stripper from that RC task. <lang lb>all$ ="" for i =0 to 10
all$ =all$ +chr$( int( 32 *rnd( 1)))
next i
all$ =all$ +"A sentence with 10 random control codes leading & trailing." +all$ print all$ print controlStripped$( all$), "after stripping."
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</lang>
Lua
<lang lua>str = " \t \r \n String with spaces \t \r \n "
print( string.format( "Leading whitespace removed: %s", str:match( "^%s*(.+)" ) ) ) print( string.format( "Trailing whitespace removed: %s", str:match( "(.-)%s*$" ) ) ) print( string.format( "Leading and trailing whitespace removed: %s", str:match( "^%s*(.-)%s*$" ) ) )</lang>
Mathematica
<lang Mathematica>StringTrim[" \n\t string with spaces \n \t "]</lang>
MATLAB / Octave
<lang matlab>% remove trailing whitespaces
str = str(1:find(~isspace(str),1,'last'));
% remove leading whitespaces
str = str(find(~isspace(str),1):end);
% removes leading and trailing whitespaces, vectorized version
f = ~isspace(str); str = str(find(f,1,'first'):find(f,1,'last');
% a built-in function, removes leading and trailing whitespaces
str = strtrim(str);</lang>
Mercury
<lang mercury>:- module top_and_tail.
- - interface.
- - import_module io.
- - pred main(io::di, io::uo) is det.
- - implementation.
- - import_module list, string.
main(!IO) :-
TestPhrase = "\t\r\n String with spaces \t\r\n ", io.format("leading ws removed: %s\n", [s(lstrip(TestPhrase))], !IO), io.format("trailing ws removed: %s\n", [s(rstrip(TestPhrase))], !IO), io.format("both removed: %s\b", [s(strip(TestPhrase))], !IO).</lang>
Nemerle
<lang Nemerle>def str = "\t\n\t A string with\nwhitespace\n\n\t "; WriteLine(str.TrimStart()); WriteLine(str.TrimEnd()); WriteLine(str.Trim()); // both ends at once, of course, internal whitespace is preserved in all 3</lang>
Oberon-2
Oxford Oberon-2 <lang oberon2> MODULE Trim; IMPORT Out,Strings,SYSTEM;
CONST (* whitespaces *) HT = 09X; VT = 0BX; FF = 0CX; GS = 1DX; US = 1FX; LF = 0AX; CR = 0DX; FS = 1CX; RS = 1EX; SPC = 20X;
PROCEDURE LTrim(VAR s: ARRAY OF CHAR); VAR j : INTEGER; BEGIN j := 0; WHILE (s[j] = HT) OR (s[j] = LF) OR (s[j] = VT) OR (s[j] = CR) OR (s[j] = FF) OR (s[j] = FS) OR (s[j] = FS) OR (s[j] = GS) OR (s[j] = RS) OR (s[j] = US) OR (s[j] = SPC) DO INC(j) END; SYSTEM.MOVE(SYSTEM.ADR(s[j]),SYSTEM.ADR(s[0]),LEN(s) - j); END LTrim;
PROCEDURE RTrim(VAR s: ARRAY OF CHAR); VAR j : INTEGER; BEGIN j := LEN(s) - 1; WHILE (j >= 0) & (s[j] = 0X) DO DEC(j) END; WHILE (j >= 0) & ((s[j] = HT) OR (s[j] = LF) OR (s[j] = VT) OR (s[j] = CR) OR (s[j] = FF) OR (s[j] = FS) OR (s[j] = FS) OR (s[j] = GS) OR (s[j] = RS) OR (s[j] = US) OR (s[j] = SPC)) DO s[j] := 0X;
DEC(j)
END END RTrim;
PROCEDURE Trim(VAR s: ARRAY OF CHAR); BEGIN LTrim(s); RTrim(s) END Trim;
VAR s: ARRAY 100 OF CHAR;
BEGIN s := " A AAA"; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);LTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; s := "AAA A "; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);RTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; s := " A AA A "; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);Trim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; s := " "; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);Trim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; s := " "; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);RTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; s := " "; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);LTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);RTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; Out.Char("[");Out.String(s);Out.String("]=");Out.Char(HT);LTrim(s);Out.Char("[");Out.String(s);Out.Char("]");Out.Ln; END Trim. </lang> Output:
[ A AAA]= [A AAA] [AAA A ]= [AAA A] [ A AA A ]= [A AA A] [ ]= [] [ ]= [] [ ]= [] []= [] []= []
Objective-C
<lang objc>#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() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *s = @" this is a string ";
NSLog(@"'%@'", s); NSLog(@"'%@'", [s ltrim]); NSLog(@"'%@'", [s rtrim]); NSLog(@"'%@'", [s trim]);
[pool release]; return 0;
}</lang>
OCaml
<lang ocaml>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 -> ""</lang>
we put the previous code in a file called "trim.ml", and then we test these functions in the toplevel:
$ ocaml # #use "trim.ml" ;; val left_pos : string -> int -> int option = <fun> val right_pos : string -> int -> int option = <fun> val trim : string -> string = <fun> val ltrim : string -> string = <fun> val rtrim : string -> string = <fun> # let s = " \t \r \n String with spaces \t \r \n " ;; val s : string = " \t \r \n String with spaces \t \r \n " # trim s ;; - : string = "String with spaces" # ltrim s ;; - : string = "String with spaces \t \r \n " # rtrim s ;; - : string = " \t \r \n String with spaces"
OpenEdge/Progress
<lang progress>DEF VAR cc AS CHAR INIT " string with spaces ".
MESSAGE
"|" + LEFT-TRIM( cc ) + "|" SKIP "|" + RIGHT-TRIM( cc ) + "|" SKIP "|" + TRIM( cc ) + "|"
VIEW-AS ALERT-BOX.</lang>
- Output:
--------------------------- Message --------------------------- |string with spaces | | string with spaces| |string with spaces| --------------------------- OK ---------------------------
Perl
<lang perl>use strict;
sub ltrim {
my $c = shift; $c =~ s/^\s+//; return $c;
}
sub rtrim {
my $c = shift; $c =~ s/\s+$//; return $c;
}
sub trim {
my $c = shift; return ltrim(rtrim($c));
}
my $p = " this is a string ";
print "'", $p, "'\n"; print "'", trim($p), "'\n"; print "'", ltrim($p), "'\n"; print "'", rtrim($p), "'\n";</lang>
Perl 6
<lang perl6>my $s = "\r\n \t\x2029 Good Stuff \x2028\n"; say $s.trim.perl; say $s.trim-leading.perl; say $s.trim-trailing.perl;</lang>
PicoLisp
<lang PicoLisp>(de trimLeft (Str)
(pack (flip (trim (flip (chop Str))))) )
(de trimRight (Str)
(pack (trim (chop Str))) )
(de trimBoth (Str)
(pack (clip (chop Str))) )</lang>
Test:
: (trimLeft " ^G ^I trimmed left ^L ") -> "trimmed left ^L " : (trimRight " ^G ^I trimmed right ^L ") -> " ^G ^I trimmed right" : (trimBoth " ^G ^I trimmed both ^L ") -> "trimmed both"
PL/I
<lang PL/I>put ( trim(text, ' ', ) ); /* trims leading blanks. */ put ( trim(text, , ' ') ); /* trims trailing blanks. */ put ( trim(text) ); /* trims leading and trailing */
/* blanks. */</lang>
To remove any white-space character(s) in a portable way:- <lang PL/I>declare whitespace character(33) value
((substr(collate(), 1, 32) || ' '));
put ( trim(text, whitespace) ); /* trims leading white space. */ put ( trim(text, , whitespace) ); /* trims trailing white space. */ put ( trim(text, whitespace, whitespace) );
/* trims leading and trailing */ /* white space. */</lang>
Prolog
Works with SWI-Prolog. <lang Prolog>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.
</lang>
Output :
?- strip. In : There are unwanted blanks here! __ Strip left : There are unwanted blanks here! __ Strip right : There are unwanted blanks here!__ Strip : There are unwanted blanks here!__ true.
SWI-Prolog has an integrated version of strip : normalize_space(-Out, +In)
?- In = ' There are unwanted blanks here! ', normalize_space(atom(Out), In). In = ' There are unwanted blanks here! ', Out = 'There are unwanted blanks here!'.
PureBasic
Note, if only spaces need to be removed, PureBasic provides commands that do this: LTrim(), RTrim(), and Trim(). To handle a larger selection of whitespace the following functions meet the task. <lang PureBasic>;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</lang>
- Output:
"Top " " Tail" "Both"
Python
<lang python>>>> 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' >>> </lang>
Retro
<lang Retro>" this is a test " ^strings'trimLeft " this is a test " ^strings'trimRight " this is a test " ^strings'trimLeft ^strings'trimRight</lang>
REXX
There are other methods to remove white space, but they are pretty obtuse compared to these simple methods (functions). <lang rexx>/*REXX program to show how to strip leading and/or trailing spaces. */
yyy=" this is a string that has leading and trailing blanks, fur shure. "
/*white space also includes tabs (VT & HT),*/ /*among other characters. */
/*all examples in each group are equivalent*/ /*only the option's first char is examined.*/
/*───────────────────────just remove the leading white space. */
noL=strip(yyy,'L') noL=strip(yyy,"l") noL=strip(yyy,'leading') g="Listen, birds / those signs cost money / so roost a while / but don't get funny / Burma-shave" noL=strip(yyy,g) /*a long way to go to fetch a pail of water.*/
/*───────────────────────just remove the trailing white space. */
noT=strip(yyy,'T') noT=strip(yyy,"t") noT=strip(yyy,'trailing') noT=strip(yyy,'trains ride the rails') j="Toughest Whiskers / In the town / We hold 'em up / You mow 'em down / Burma-Shave" noT=strip(yyy,j)
/*───────────────────────remove leading and trailing white space. */
noB=strip(yyy) noB=strip(yyy,) noB=strip(yyy,'B') noB=strip(yyy,"b") noB=strip(yyy,'both') opt='Be a noble / Not a knave / Caesar uses / Burma-Shave' noB=strip(yyy,opt)
/*───────────────────────also remove all superfluous white space, */
noX=space(yyy) /* including white space between words. */</lang>
Ruby
<lang ruby>s = " \t\v\r\n\ffoo \t\v\r\n\f" p [s, s.lstrip, s.rstrip, s.strip]</lang>
- Output:
[" \t\v\r\n\ffoo \t\v\r\n\f", "foo \t\v\r\n\f", " \t\v\r\n\ffoo", "foo"]
Run BASIC
Run BASIC has trim command for left and right <lang runbasic>string$ = " abcdefg "
print " Top:";ltrim$(string$) ' top left trim print "Bottom:";mid$(trim$("|"+string$),2) ' bottom right trim print " Both:";trim$(string$) ' both left and right
function ltrim$(s$)
s$ = trim$(s$ + "|") ltrim$ = left$(s$,len(s$) - 1)
end function end</lang>
Top:abcdefg Bottom: abcdefg Both:abcdefg
Sather
<lang sather>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;</lang>
Scala
<lang scala>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)+"|")
}</lang>
- Output:
original : | � String with spaces | trimLeft : |String with spaces | trimRight : | � String with spaces| trimRight2: | � String with spaces| trim : |String with spaces|
Smalltalk
<lang smalltalk>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.</lang>
Tcl
Whitespace stripping is done with string trim
and related commands:
<lang tcl>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]<"</lang>
- Output:
original: > hello world < trimmed head: >hello world < trimmed tail: > hello world< trimmed both: >hello world<
TI-83 BASIC
<lang ti-83b> 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+"'" </lang>
TUSCRIPT
<lang tuscript>$$ 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,">|"</lang>
- Output:
string <| sentence w/whitespace before and after >| trimmed on top <|sentence w/whitespace before and after >| trimmed on tail <| sentence w/whitespace before and after>| trimmed on both <|sentence w/whitespace before and after>|
TXR
Here, no builtin functions are used, just text pattern matching logic. Two functions are written, conforming to the proper filter convention, and then employed as filters. <lang txr>@(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]*/}@middle@/[\t ]+/ @ (bind out `@blanks@middle`) @ (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)</lang>
- Output:
$ echo "" | txr trim.txr - trim-left: [] trim_right: [] trim_both: [] $ echo "a" | txr trim.txr - trim-left: [a] trim_right: [a] trim_both: [a] $ echo " a" | txr trim.txr - trim-left: [a] trim_right: [ a] trim_both: [a] $ echo " a " | txr trim.txr - trim-left: [a ] trim_right: [ a] trim_both: [a] $ echo " a b " | txr trim.txr - trim-left: [a b ] trim_right: [ a b] trim_both: [a b]
Vala
Strip Leading White Space
<lang vala>string s = " word "; string s_chug = s.chug();</lang>
Strip Trailing White Space
<lang vala>string s = " word "; string s_chomp = s.chomp();</lang>
Strip Leading & Trailing White Space
<lang vala>string s = " word "; string s_strip = s.strip();</lang>
Ursala
<lang Ursala>#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 '</lang>
- The
white
predicate tests an argument for whiteness by either comparing it to a literal space character or testing whether the singleton list containing it is of a string (%s
) type. - The
-~
postfix operator takes a predicate to a function that takes a string to a pair of strings whose concatenation is the original string and whose left side is the maximal prefix of the original string whose members satisfy the predicate. - The
r
suffix on the-~
predicate extracts the right side of the pair of strings in the result. - The
~-
operator is similar to the-~
operator except that is concerned with the maximal suffix whose members satisfy the predicate. - The
l
suffix extracts the right side.
- Output:
< 'string with spaces ', ' string with spaces', 'string with spaces'>
- Programming Tasks
- String manipulation
- Ada
- AutoHotkey
- AWK
- BASIC
- Bracmat
- C
- C++
- C sharp
- D
- Delphi
- Pascal
- DWScript
- Euphoria
- Forth
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- Liberty BASIC
- Lua
- Mathematica
- MATLAB
- Octave
- Mercury
- Nemerle
- Oberon-2
- Objective-C
- OCaml
- OpenEdge/Progress
- Perl
- Perl 6
- PicoLisp
- PL/I
- Prolog
- PureBasic
- Python
- Retro
- REXX
- Ruby
- Run BASIC
- Sather
- Scala
- Smalltalk
- Tcl
- TI-83 BASIC
- TUSCRIPT
- TXR
- Vala
- Ursala