Another 5 minutes for Tcl

->Strings, ->lists and ->arrays

Strings and pattern matching

The string command

Strings are the basic data items in Tcl. The general syntax of the Tcl string command is
string operation stringvalue otherargs
tcl> string length abc
3
tcl> string index abc 1
b
tcl> string range abcd 1 end
bcd
To compare two strings you can also use ==. But that might not work as you wanted with strings containing digits because 1 equals 1.00 (but not in a string sense).
     if [string compare $a $b] {puts "$a and $b differ"} 
Use 'first' or 'last' to look for a substring. The return value is the index of the first character of the substring within the string.
tcl> string first abc xxxabcxxxabcxx
3
tcl> string last abc xxxabcxxxabcxxx
9
tcl> string last abc xxxxxx
-1
The 'string match' command uses the glob-style pattern matching like many UNIX shell commands do.
Glob-style syntax
* Matches any number of any character.
? Matches any single character.
[ ] One of a set of characters like [a-z].
tcl> string match {a[0-9]bc?def\?ghi*} a5bcYdef?ghixxx
1
tcl> set a [string tolower abcXY]
abcxy
tcl> string toupper $a
ABCXY
tcl> string trim "  abc  "
abc
tcl> string trimright "xxabcxxxx" x
xxabc
tcl> string trimleft "  a  bc" 
a  bc
Here comes a small example that finds the word with 'x' in a sentence.
tcl> set s {abc dexfgh ijklm}
tcl> string first x $s
6
tcl> set start  [string wordstart $s 6]  ;# start position
4 
tcl> set end    [string wordend $s 6]    ;# position after word
10 
tcl> string range $s $start [expr $end - 1]
dexfgh

More commands dealing with strings

tcl> set a abc
tcl> append a def
abcdef

tcl> puts [format "%8s\t%8.4f" $a -12.7]
  abcdef        -12.7000
tcl> scan "distance 12.34m" "%s%f%c" what value unit
3 

Regular Expressions

Regular expression syntax
. Matches any character.
* Matches zero or more.
? Matches zero or one.
( ) Groups a sub-pattern.
| Alternation.
[ ] Set of characters like [a-z]. [^0-9] means that numbers are excluded.
^ Beginning of the string.
$ End of string.
tcl> regexp {hello|Hello} Hello
1
tcl> regexp {[hH]ello} Hello
1
tcl> regexp {[0-9]\.([a-z])([a-wyz]*)} "xxx8.babcxxxxxx" match s1 s2
1
tcl> puts "$match $s1 $s2"
8.babc b abc

tcl> regsub {[0-9]\.([a-z])([a-wyz]*)} "xxx8.babcxxxxxx" {__\1__\2__&__}  var; puts $var
xxx__b__abc__8.babc__xxxxxx


Lists

Tcl lists are just strings with a special interpretation. Separated by white space or grouped with braces or quotes.
tcl> set mylist "a b {c d}"
tcl> set mylist [list a b {c d}]         ;# same as above
tcl> foreach element $mylist {puts $element}
a
b
c d
Here several Tcl commands related to lists:
tcl> lindex $mylist 1         ;# note the index starts with 0
b
tcl> llength $mylist          ;# 'c d' is only one element
3

tcl> lappend mylist {g h}     ;# this time the list name 'mylist' is used
a b {c d} {g h}
tcl> lrange $mylist 2 end
{c d} {g h}
tcl> linsert $mylist 3 E x              ;# note that we don't give the list name here!
a b {c d} E x {g h}
tcl> set mylist [linsert $mylist 3 E x]  ;# to change the list we have to use 'set'
a b {c d} E x {g h}

tcl> lsearch -exact $mylist E        ;# other modes are the default '-glob' and '-regexp'
3
tcl> lreplace $mylist 3 5 e f {g h i} 
a b {c d} e f {g h i}
tcl> lreplace $mylist 3 3            ;# delete element 3

tcl> lsort "-1.2 -1 -900 -90 1e-3 10"
-1 -1.2 -90 -900 10 1e-3
tcl> lsort -real "-1.2 -1 -900 -90 1e-3 10"  ;# other flags are '-ascii','-integer','-increasing','-decreasing'
-900 -90 -1.2 -1 1e-3 10

tcl> list "a b" c
{a b} c
tcl> concat "a b" c
a b c

tcl> join "{} usr local bin" /
/usr/local/bin
tcl> split /usr/my-local/bin /-
{} usr my local bin


Arrays

tcl> array exists a
0
tcl> set a(0) 0.12;   set a(1) 1.23;   set a(name) hello  

tcl> array size a
3
tcl> array names a
0 name 1
tcl> array get a 
0 0.12 name hello 1 1.23

The initialization could have been done with:
tcl> array set a "0 0.12 name hello 1 1.23"
tcl> array set b [array get a]     ;# Copy array b from a:
Other array commands are startsearch, nextelement, anymore, donesearch.

"Much more Tcl!"


Maintainer: westphal@ira.uka.de