JykkeDaMan has asked for the wisdom of the Perl Monks concerning the following question:

Hello.

How do I parse TCL list elements out of string like tcl list?
TCL list examples:
"eka toka kolo"
"eka {toka soka} kolo"
"{eka seka leka seka} {toka soka {roka loka moka} doka}{{kolo nolo} {{solo molo} tolo} holo rolo}"

Something like this:
my @elements = &parseTclList($tclList);

Replies are listed 'Best First'.
Re: Parse TCL list?
by PodMaster (Abbot) on Nov 08, 2003 at 11:16 UTC
    What are "TCL list elements"? (you wouldn't expect me to go learn about TCL now) I suspect you may need Regexp::Common, as in
    use Regexp::Common qw /balanced/; my( @ek ) = ( "eka toka kolo", "eka {toka soka} kolo", "{eka seka leka seka} {toka soka {roka loka moka} doka}{{kolo nolo} {{ +solo molo} tolo} holo rolo}" ); for my $str ( @ek ){ print "$_\n" for $str =~ /$RE{balanced}{-parens=>'{}'}/g; } __END__ {toka soka} {eka seka leka seka} {toka soka {roka loka moka} doka} {{kolo nolo} {{solo molo} tolo} holo rolo}
    but that's just a guess.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: Parse TCL list?
by castaway (Parson) on Nov 08, 2003 at 15:17 UTC
    My node Parsing Text into Arrays.. sparked off a whole lot of answers about how to do this sort of thing, depending on how secure you want it..

    (Interesting, I used none of the suggestions in the end, the Parse::RecDescent one was the most complete, but too slow.. )

    C.

Re: Parse TCL list?
by JykkeDaMan (Novice) on Nov 08, 2003 at 13:10 UTC
    Hi.

    Yes, that's it. Im not 100% sure if the second line is even possible....

    Is there a way to do "or" for strings like those examples? What I mean is if the list is like the first one, there is no '{' at all (so its easy to split by \s), but the second one should return 'eka', 'toka soka' and 'kolo'. The third one works okay with your example.

      In regular expressions, the | symbol means "or".
      #! /usr/bin/perl use strict; use Regexp::Common; my $string = "@ARGV"; print "$_\n" for $string =~ /(\w+|$RE{balanced}{-parens=>'{}'})/g;
      That seems to produce correct output for all of your examples.