[Newbies] String construction and replacement

Michael van der Gulik mikevdg at gmail.com
Sun Feb 1 20:49:41 UTC 2009


On Mon, Feb 2, 2009 at 8:46 AM, Sebastian Nozzi <sebnozzi at googlemail.com>wrote:

> Hello List,
>
> I've been struggling a bit with some basics about Strings for which I
> couldn't find an answer (yet).
>
> 1) How to construct a String from Characters?
>
> For example, I want to construct a String from the Chatacter literals:
>
> $H $I
> Character cr
> $T $H $E $R $E
>

If you're dealing with less than four characters, you could do:

a := String with: $H with: $I with: Character cr with: $T.

Otherwise, I'm not aware of any trivial way to do this.

The first issue is that you need to have all those characters available as a
collection somehow (without using a String). My best effort, without adding
convenience methods to the String class, is:

a := #( $H $I $- $T $H $E $R $E ). "Makes an array of literals - I never
liked this syntax though"

You have to manually put the "Character cr" in there; I'm not aware of any
way to declare it as a literal like that:

a at: 3 put: Character cr.

And then you can do Smalltalk magic with it:

b := a inject: '' into: [ :each :sum | each, sum asString]. "Makes 8 copies
of a String; inefficient"

If there were more than just a handful of characters (e.g. writing to a
file), then you'd want to use streams instead:

c := WriteStream on: (String new: a size).  " It's important to make a good
estimate of size here "
c nextPutAll: a.
b := c contents.

c is a stream with a String as a target, so "nextPutAll:" will accept any
collection of characters and "nextPut:" will accept any individual
character.



> 2) How to replace a sequence of Characters in a String for others?
>
> For exaple, I want to replace every 'HI' (in this case only one) for
> 'HELLO' in the String above (not necesarily destructively, getting a
> new String is also ok). Is there a quick way to do that?;;
>


This is something that I don't know off the top of my head, so I'm going to
give you a small insight as to how I work this out.

First, I bring up the browser and intuitively go to the String class. I have
a quick look at the method categories, and see "converting" and "copying"
which might be useful. I notice "copyReplaceTokens:with:" which invokes
"copyReplaceAll:with:asTokens".

I highlight the invocation of "copyReplaceAll:with:asTokens" and press alt-m
to see which classes implement this. But then a little lightbulb goes off in
my head; perhaps "copyReplaceAll:with:" exists. It does - in class
SequencableCollection.

I also discover "replaceAll:with" on a hunch as well, but it doesn't work
and doesn't give any errors. A bug maybe?

So you can do this:

d := b copyReplaceAll: 'HI' with: 'HELLO'.

Now, I know that there are also more advanced things you can do, such as
replacing using regular expressions, but I think that is in a downloadable
package somewhere. You'll need to Google for it.

Gulik.

-- 
http://people.squeakfoundation.org/person/mikevdg
http://gulik.pbwiki.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/beginners/attachments/20090202/6c4d06aa/attachment.htm


More information about the Beginners mailing list