Strip a set of characters from a string: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Ada code)
Line 4: Line 4:
<lang pseudocode> print stripchars("She was a soul stripper. She took my heart!","aei")
<lang pseudocode> print stripchars("She was a soul stripper. She took my heart!","aei")
Sh ws soul strppr. Sh took my hrt!</lang>
Sh ws soul strppr. Sh took my hrt!</lang>
=={{header|Ada}}==

<lang Ada>with Ada.Text_IO;

procedure Strip_Characters_From_String is

function Strip(The_String: String; The_Characters: String)
return String is
Keep: array (Character) of Boolean := (others => True);
Result: String(The_String'Range);
Last: Natural := Result'First-1;
begin
for I in The_Characters'Range loop
Keep(The_Characters(I)) := False;
end loop;
for J in The_String'Range loop
if Keep(The_String(J)) then
Last := Last+1;
Result(Last) := The_String(J);
end if;
end loop;
return Result(Result'First .. Last);
end Strip;

S: String := "She was a soul stripper. She took my heart!";

begin -- main
Ada.Text_IO.Put_Line(Strip(S, "aei"));
end Strip_Characters_From_String;</lang>

Output:

<pre>> ./strip_characters_from_string
Sh ws soul strppr. Sh took my hrt!</pre>


=={{header|C}}==
=={{header|C}}==

Revision as of 14:12, 16 August 2011

Task
Strip a set of characters from a string
You are encouraged to solve this task according to the task description, using any language you may know.

The task is to create a function that strips a set of characters from a string. The function should take two arguments: the first argument being a string to stripped and the second, a string containing the set of characters to be stripped. The returned string should contain the first string, stripped of any characters in the second argument:

<lang pseudocode> print stripchars("She was a soul stripper. She took my heart!","aei") Sh ws soul strppr. Sh took my hrt!</lang>

Ada

<lang Ada>with Ada.Text_IO;

procedure Strip_Characters_From_String is

  function Strip(The_String: String; The_Characters: String)
                 return String is
     Keep:   array (Character) of Boolean := (others => True);
     Result: String(The_String'Range);
     Last:   Natural := Result'First-1;
  begin
     for I in The_Characters'Range loop
        Keep(The_Characters(I)) := False;
     end loop;
     for J in The_String'Range loop
        if Keep(The_String(J)) then
           Last := Last+1;
           Result(Last) := The_String(J);
        end if;
     end loop;
     return Result(Result'First .. Last);
  end Strip;
  S: String := "She was a soul stripper. She took my heart!";

begin -- main

  Ada.Text_IO.Put_Line(Strip(S, "aei"));

end Strip_Characters_From_String;</lang>

Output:

> ./strip_characters_from_string 
Sh ws  soul strppr. Sh took my hrt!

C

<lang c>#include <string.h>

  1. include <malloc.h>
  2. include <stdio.h>
 /* checks if character exists in list */

int contains( char character, char * list ){

 while( *list ){
   if( character == *list )
     return 1;
   ++ list;
 }
 return 0;

}


 /* removes all chars from string */

char * strip_chars( char * string, char * chars ){

 char * newstr = malloc( strlen( string ) );
 int counter = 0;
 while( *string ){
   if( contains( *string, chars ) != 1 ){
     newstr[ counter ] = *string;
     ++ counter;
   }
   ++ string;
 }
 return newstr;

}


int main( int argc, char ** argv ){

 char * new = strip_chars( "She was a soul stripper. She took my heart!", "aei" );
 printf( "%s\n", new );
 free( new );
 return 0;

}</lang>

Result:

Sh ws  soul strppr. Sh took my hrt!

With table lookup

<lang C>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>

char *strip(char * str, char *pat) { /* char replacement is typically done with lookup tables if * the replacement set can be large: it turns O(m n) into * O(m + n). * If same replacement pattern is going to be applied to many * strings, it's better to build a table beforehand and reuse it. * If charset is big like unicode, table needs to be implemented * more efficiently, say using bit field or hash table -- it * all depends on the application. */ int i = 0, tbl[128] = {0}; while (*pat != '\0') tbl[(int)*(pat++)] = 1;

char *ret = malloc(strlen(str)); do { if (!tbl[(int)*str]) ret[i++] = *str; } while (*(str++) != '\0');

/* assuming realloc is efficient and succeeds; if not, we could * do a two-pass, count first, alloc and strip second */ return realloc(ret, i); }

int main() { char * x = strip("She was a soul stripper. She took my heart!", "aei"); printf(x); free(x);

return 0; }</lang>Output same as above.

C++

Note: this uses a C++0x lambda function <lang cpp>#include <algorithm>

  1. include <iostream>
  2. include <string>

std::string stripchars(std::string str, const std::string &chars) {

   str.erase(
       std::remove_if(str.begin(), str.end(), [&](char c){
           return chars.find(c) != std::string::npos;
       }),
       str.end()
   );
   return str;

}

int main() {

   std::cout << stripchars("She was a soul stripper. She took my heart!", "aei") << '\n';
   return 0;

}</lang> Output:

Sh ws  soul strppr. Sh took my hrt!

C#

<lang C sharp> using System;

public static string RemoveCharactersFromString(string testString, string removeChars) {

   char[] charAry = removeChars.ToCharArray();
   string returnString = testString;
   foreach (char c in charAry)
   {
       while (returnString.IndexOf(c) > -1)
       {
           returnString = returnString.Remove(returnString.IndexOf(c), 1);
       }
   }
   return returnString;

} </lang>

Usage: <lang C sharp> using System;

class Program {

   static void Main(string[] args)
   {
       string testString = "She was a soul stripper. She took my heart!";
       string removeChars = "aei";
       Console.WriteLine(RemoveCharactersFromString(testString, removeChars));
   }

} </lang> Output:

Sh ws  soul strppr. Sh took my hrt!

Using Regex: <lang C sharp> using System; using System.Text.RegularExpressions;

private static string RegexRemoveCharactersFromString(string testString, string removeChars) {

   string pattern = "[" + removeChars + "]";
   return Regex.Replace(testString, pattern, "");

}</lang>

Common Lisp

<lang lisp>(defun strip-chars (str chars)

 (remove-if (lambda (ch) (find ch chars)) str))

(strip-chars "She was a soul stripper. She took my heart!" "aei")

=> "Sh ws soul strppr. Sh took my hrt!"

</lang>

D

<lang d>import std.stdio, std.string;

void main() {

   auto s = "She was a soul stripper. She took my heart!";
   auto ss = "Sh ws  soul strppr. Sh took my hrt!";
   assert(s.removechars("aei") == ss);

}</lang>

Delphi

<lang Delphi>program StripCharacters;

{$APPTYPE CONSOLE}

uses SysUtils;

function StripChars(const aSrc, aCharsToStrip: string): string; var

 c: Char;

begin

 Result := aSrc;
 for c in aCharsToStrip do
   Result := StringReplace(Result, c, , [rfReplaceAll, rfIgnoreCase]);

end;

const

 TEST_STRING = 'She was a soul stripper. She took my heart!';

begin

 Writeln(TEST_STRING);
 Writeln(StripChars(TEST_STRING, 'aei'));

end.</lang>

Go

<lang go>package main

import (

   "fmt"
   "strings"

)

func stripchars(str, chr string) string {

   return strings.Map(func(rune int) int {
       if strings.IndexRune(chr, rune) < 0 {
           return rune
       }
       return -1
   }, str)

}

func main() {

   fmt.Println(stripchars("She was a soul stripper. She took my heart!",
       "aei"))

}</lang> Output:

Sh ws  soul strppr. Sh took my hrt!

Haskell

I decided to make the string the second argument and the characters the first argument, because it is more likely for someone to partially apply the characters to be stripped (making a function that strips certain characters), than the string. <lang haskell>stripChars :: String -> String -> String stripChars = filter . flip notElem</lang>

testing in GHCI:

> stripChars "aei" "She was a soul stripper. She took my heart!"
"Sh ws  soul strppr. Sh took my hrt!"

Icon and Unicon

The following works in both languages: <lang unicon>procedure main(A)

   cs := \A[1] | 'aei'   # argument is set of characters to strip
   every write(stripChars(!&input, cs))  # strip all input lines

end

procedure stripChars(s,cs)

   ns := ""
   s ? while ns ||:= (not pos(0), tab(upto(cs)|0)) do tab(many(cs)))
   return ns

end</lang>

Sample runs:

->strip
She was a soul stripper. She took my heart!
Sh ws  soul strppr. Sh took my hrt!
Aardvarks are ant eaters.
Ardvrks r nt trs.
->strip AEIOUaeiou
Aardvarks are ant eaters.
rdvrks r nt trs.
->

J

Solution:
The dyadic primitive -. (Less) is probably the simplest way to solve this task.

Example Usage: <lang j> 'She was a soul stripper. She took my heart!' -. 'aei' Sh ws soul strppr. Sh took my hrt!</lang>

Java

<lang java>class StripChars {

   public static String stripChars(String inString, String toStrip) {
       return inString.replaceAll("[" + toStrip + "]", "");
   }
   public static void main(String[] args) {
       String sentence = "She was a soul stripper. She took my heart!";
       String chars = "aei";
       System.out.println("sentence: " + sentence);
       System.out.println("to strip: " + chars);
       System.out.println("stripped: " + stripChars(sentence, chars));
   }

}</lang>

output:

sentence: She was a soul stripper. She took my heart!
to strip: aei
stripped: Sh ws  soul strppr. Sh took my hrt!

Lua

<lang lua>function stripchars( str, chr )

   local s = ""
   for g in str:gmatch( "[^"..chr.."]" ) do
	s = s .. g
   end
   return s

end

print( stripchars( "She was a soul stripper. She took my heart!", "aei" ) )</lang>

Liberty BASIC

<lang lb> Print stripchars$("She was a soul stripper. She took my heart!", "aei", 1) End

Function stripchars$(strip$, chars$, num)

   For i = 1 To Len(strip$)
       If Mid$(strip$, i, 1) <> Mid$(chars$, num, 1) Then
           stripchars$ = (stripchars$ + Mid$(strip$, i, 1))
       End If
   Next i
   If (num <= Len(chars$)) Then stripchars$ = stripchars$(stripchars$, chars$, (num + 1))

End Function

</lang>

Nemerle

<lang Nemerle>StripChars( text : string, remove : string ) : string {

   def chuck = Explode(remove);
   Concat( "", Split(text, chuck))

}</lang>

Objective-C

Works with: Mac OS X version 10.5+
Works with: iOS

<lang objc>@interface NSString (StripCharacters) - (NSString *) stripCharactersInSet: (NSCharacterSet *) chars; @end

@implementation NSString (StripCharacters) - (NSString *) stripCharactersInSet: (NSCharacterSet *) chars {

   return [[self componentsSeparatedByCharactersInSet:chars] componentsJoinedByString:@""];

} @end</lang>

To use: <lang objc> NSString *aString = @"She was a soul stripper. She took my heart!";

   NSCharacterSet* chars = [NSCharacterSet characterSetWithCharactersInString:@"aei"];
   // Display the NSString.
   NSLog(@"%@", [aString stripCharactersInSet:chars]);</lang>

OCaml

<lang ocaml>let stripchars s cs =

 let len = String.length s in
 let res = String.create len in
 let rec aux i j =
   if i >= len then String.sub res 0 j
   else if String.contains cs s.[i] then
     aux (succ i) (j)
   else begin
     res.[j] <- s.[i];
     aux (succ i) (succ j)
   end
 in
 aux 0 0</lang>

testing in the toplevel:

# stripchars "She was a soul stripper. She took my heart!" "aei" ;;
- : string = "Sh ws  soul strppr. Sh took my hrt!"

PARI/GP

GP should not be used for string manipulation. A good solution to this problem would probably involve system("perl -e... <lang parigp>stripchars(s, bad)={

 bad=Set(Vec(Vecsmall(bad)));
 s=Vecsmall(s);
 my(v=[]);
 for(i=1,#s,if(!setsearch(bad,s[i]),v=concat(v,s[i])));
 Strchr(v)

}; stripchars("She was a soul stripper. She took my heart!","aei")</lang>

Perl

Caveat: in this version hyphens in the second argument can be used to specify ranges; if you need to actually strip hyphens, you need to put a backslash before it <lang perl>sub stripchars {

   my ($s, $chars) = @_;
   eval("\$s =~ tr/$chars//d;");
   return $s;

}

print stripchars("She was a soul stripper. She took my heart!", "aei"), "\n";</lang> Output:

Sh ws  soul strppr. Sh took my hrt!

Perl 6

<lang perl6>sub strip_chars ( $s, $chars ) {

   return $s.trans( $chars.comb X=>  );

}

say strip_chars( 'She was a soul stripper. She took my heart!', 'aei' );</lang>

Output:

Sh ws  soul strppr. Sh took my hrt!

PHP

<lang php><?php function stripchars($s, $chars) {

   return str_replace(str_split($chars), "", $s);

}

echo stripchars("She was a soul stripper. She took my heart!", "aei"), "\n"; ?></lang> Output:

Sh ws  soul strppr. Sh took my hrt!

PicoLisp

<lang PicoLisp>(de strDiff (Str1 Str2)

  (pack (diff (chop Str1) (chop Str2))) )</lang>

Output:

: (strDiff "She was a soul stripper. She took my heart!" "aei")
-> "Sh ws  soul strppr. Sh took my hrt!"

PL/I

<lang PL/I> strip_chars: procedure (text, chars) returns (character (100) varying);

  declare text character (*) varying, chars character (*) varying;
  declare out_text character (100);
  declare ch character (1);
  declare (i, j) fixed binary;
  j = 0;
  do i = 1 to length(text);
     ch = substr(text, i, 1);
     if index(chars, ch) = 0 then
        do; j = j + 1; substr(out_text, j, 1) = ch; end;
  end;
  return (substr(out_text, 1, j) );

end strip_chars; </lang>

PureBasic

PureBasic uses a single (for ASCII) or a two-byte (for Unicode) null to signal the end of a string. Nulls are thus excluded from the allowable characters to strip as they can't be included in a PureBasic string. <lang PureBasic>Procedure.s stripChars(source.s, charsToStrip.s)

 Protected i, *ptrChar.Character, length = Len(source), result.s
 *ptrChar = @source
 For i = 1 To length
   If Not FindString(charsToStrip, Chr(*ptrChar\c))
     result + Chr(*ptrChar\c)
   EndIf
   *ptrChar + SizeOf(Character)
 Next
 ProcedureReturn result 

EndProcedure

If OpenConsole()

 PrintN(stripChars("She was a soul stripper. She took my heart!", "aei"))
 
 Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
 CloseConsole()

EndIf</lang> Sample output:

Sh ws  soul strppr. Sh took my hrt!

Python

Works with: Python version 2.6+

<lang python>>>> def stripchars(s, chars): ... return s.translate(None, chars) ... >>> stripchars("She was a soul stripper. She took my heart!", "aei") 'Sh ws soul strppr. Sh took my hrt!'</lang>

Works with: Python version 2.x

<lang python>>>> import string >>> def stripchars(s, chars): ... return s.translate(string.maketrans("", ""), chars) ... >>> stripchars("She was a soul stripper. She took my heart!", "aei") 'Sh ws soul strppr. Sh took my hrt!'</lang>

Implemented manually: <lang python>>>> def stripchars(s, chars): ... return "".join(c for c in s if c not in chars) ... >>> stripchars("She was a soul stripper. She took my heart!", "aei") 'Sh ws soul strppr. Sh took my hrt!'</lang>

Ruby

<lang ruby>>> "She was a soul stripper. She took my heart!".delete("aei") => "Sh ws soul strppr. Sh took my hrt!"</lang>

Standard ML

<lang sml>fun stripchars (string, chars) = let

 fun aux c =
   if String.isSubstring (str c) chars then
     ""
   else
     str c

in

 String.translate aux string

end</lang>

testing in the interpreter:

- stripchars ("She was a soul stripper. She took my heart!", "aei") ;
val it = "Sh ws  soul strppr. Sh took my hrt!" : string

Tcl

<lang tcl>proc stripchars {str chars} {

   foreach c [split $chars ""] {set str [string map [list $c ""] $str]}
   return $str

}

set s "She was a soul stripper. She took my heart!" puts [stripchars $s "aei"]</lang>

Ursala

Normally there's no need to define this operation because it's built in. <lang Ursala>strip = ~&j

  1. cast %s

test = strip('she was a soul stripper. she took my heart','aei')</lang> output:

'sh ws  soul strppr. sh took my hrt'