Re: format statement: Expanding a string
- From: Kaitzschu <kaitzschu@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Thu, 2 Mar 2006 18:30:56 +0200
On Thu, 2 Mar 2006, Andreas Leitgeb wrote:
So what one really needs in this situation is a procedure or command that does the following for a given string:
1.) try to treat it as list: if it works out,
return [lrange $str 0 end].
2.) if any non-blank prefix of the string is acceptable as
a list, find a maximal such prefix, convert that to a
list, and apply "3.)" on the rest.
3.) apply something like [split] on the rest, or treat the
rest as one item.
The second of that is non-trivial on tcl-level, especially when taking performance into account.
Trivial it is, performing well is out of the question :)
I'm not proposing any new core-features (at least not on this topic), but if someone wrote a "reasonable list parser", it might be a valueable gem on wiki or tcllib.
This is just something I cooked together while waiting for Married.. with Children to begin. Now it begins, so I'll post this now. Bye.
<some code below>
package require Tcl 8.5; # lassign
# REAsonable LiSt PArser
# not REAsonable List pARSEr
proc realspa {victim} {
# so, if it is a list, then we'll return it
if {![catch {llength $victim}]} {return [lrange $victim 0 end]}
# so, it isn't a list. fine by me
# there shall be no empty units in either end
set victim [string trim $victim]
# then we need something to cut this at
set cil [regexp -all -indices -inline {\s+} $victim]
# there are basically two ways to find out where a string is no more a list
# 1) add stuff from the beginning until it breaks
# 2) take stuff from the end until it doesn't break
# 1 is the easy way out, but it'll break in my example too early
# so case 2 it'll be
# indices need to be reversed (courtesy of KPV)
set st -1
set en [llength $cil]
foreach tm $cil {
if {[incr st] >= [incr en -1]} {break}
lset cil $st [lindex $cil $en]
lset cil $en $tm
# http://wiki.tcl.tk/43 has following line too much
# incr st
}
# puts "cil=$cil"
foreach sep $cil {
lassign $sep s e
# puts "s=$s, e=$e, r=[string range $victim 0 $s-1]"
if {![catch {llength [string range $victim 0 $s-1]}]} {break}
}
# at this point we should know where it broke, and the rest is final cell
set lst [lrange [string range $victim 0 $s-1] 0 end]
lappend lst [string range $victim $e+1 end]
}
set t "this is one {malfor matted} {list"
puts "trying out >>$t\ninvalid list? [expr {[catch {llength $t}]?yes:no}]"
set l [realspa $t]
puts "recovered (or used) [llength $l] cells"
foreach i $l {puts "->$i<<<"}
<no more code here>
--
-Kaitzschu
s="TCL ";while true;do echo -en "\r$s";s=${s:1:${#s}}${s:0:1};sleep .1;done
.
- References:
- format statement: Expanding a string
- From: Scott Brown
- Re: format statement: Expanding a string
- From: Don Porter
- Re: format statement: Expanding a string
- From: Sektor van Skijlen
- Re: format statement: Expanding a string
- From: Scott Brown
- Re: format statement: Expanding a string
- From: Ralf Fassel
- Re: format statement: Expanding a string
- From: suchenwi
- Re: format statement: Expanding a string
- From: Andreas Leitgeb
- format statement: Expanding a string
- Prev by Date: Re: copy image to windows clipboard?
- Next by Date: Re: freewrap and xml extension
- Previous by thread: Re: format statement: Expanding a string
- Next by thread: Re: format statement: Expanding a string
- Index(es):