How to split string and store in list via TCL
Asked Answered
tcl
R

6

6

Is there a way to split strings and save in a list ? How to split string and save in two list For example, I have a string where I split several string with =:

a=1
b=2
c=3
d=4

and then I want to create two list like this [a,b,c,d] and [1,2,3,4]:

Rockett answered 28/10, 2013 at 5:46 Comment(2)
a=1,b=2,c=3,d=4 is a single string?Pinwork
yes but there are no comma in between and they all are in new line for example a=1 in new line b=2 and so onRockett
A
10

Following is a simple tcl code

set s "a=1\nb=2\nc=3\nd=4"
set s [split $s "\n"]
foreach e $s {
    set e [split $e "="]
    lappend l1 [lindex $e 0]
    lappend l2 [lindex $e 1]
}

Now you have list l1 with [a b c d] and l2 has [1 2 3 4]

Achelous answered 17/1, 2019 at 19:51 Comment(0)
A
6

The simplest way is to read all the data in, split into lines, and then use regexp with each line to extract the pieces.

set f [open "theFile.txt"]
set lines [split [read $f] "\n"]
close $f

set keys [set values {}]
foreach line $lines {
    if {[regexp {^([^=]*)=(.*)$} $line -> key value]} {
        lappend keys $key
        lappend values $value
    } else {
        # No '=' in the line!!!
    }
}

# keys in $keys, values in $values

puts "keys = \[[join $keys ,]\]"
puts "values = \[[join $values ,]\]"

Run that (assuming that the filename is right) and you'll get output like:

keys = [a,b,c,d]
values = [1,2,3,4]

Collecting two lists like that might not be the best thing to do with such stuff. Often, it is better to instead to store in an array:

# Guarded by that [regexp] inside the foreach
set myArray($key) $value

Like that, you can do lookups by name rather than having to manually search. Assuming that keys are unique and order doesn't matter.

Ambulatory answered 28/10, 2013 at 10:12 Comment(1)
+1 for arrays. use parray to inspect it.Thaumatology
H
3

A simple way might be using a loop:

% set lines "a=1\nb=2\nc=3\nd=4"
a=1
b=2
c=3
d=4
% set expressionList [split $lines "\n"]
a=1 b=2 c=3 d=4
% set var [list]
% set val [list]
% foreach i $expressionList {
    set variable [lindex [split $i "="] 0]
    set value [lindex [split $i "="] 1]
    lappend val $value
    lappend var $variable
}
% puts $var
a b c d
% puts $val
1 2 3 4

If you don't mind a regex, you might try something like this:

% set lines "a=1\nb=2\nc=3\nd=4"
a=1
b=2
c=3
d=4
% set var [regexp -inline -lineanchor -all -- {^[^=\n\r]+} $lines]
a b c d
% set val [regexp -inline -lineanchor -all -- {[^=\n\r]+$} $lines]
1 2 3 4
Handmaiden answered 28/10, 2013 at 6:48 Comment(0)
G
2

If replacing the equals sign characters in $data with blanks always leaves a proper, even-valued list (as in the example) it can be done a lot simpler:

set dict [string map {= { }} $data]
set keys [dict keys $dict]
set values [dict values $dict]

Documentation: dict, set, string

Gassy answered 18/8, 2014 at 15:51 Comment(0)
P
1

Let say your strings placed in file abc.txt in the following order

a=1
b=2
c=3
d=4

You need to create 2 lists, one for numbers and one for characters:

set number_list [list]
set char_list   [list]

set fh [open "abc.txt" "r"]

while {[gets $fh line] != -1} {
    regexp -- {(\S+)=(\S+)} $line foo char number
    lappend char_list   $char
    lappend number_list $number
}

close $fh

puts $char_list
puts $number_list
Peery answered 28/10, 2013 at 7:4 Comment(0)
E
0

This is pretty old, but I would actually go about it differently... Something like the following, considering that the string is [a=1\nb=1\n ... etc.] with variable name "str":

# determine num entries in string
set max [llength $str]

#create new strings (alph & num) based on split string
set i 0
set str [split $str \n]
set alph []
set num []
while {$i < $max} {
    set alph "$alph [lindex [split [lindex $str $i] "="] 0]
    set num "$num [lindex [split [lindex $str $i] "="] 1]
incr i}

Maybe just personal preference, but seems simplest to me; code was not tested, but it's similar to something I was just working on.

Expressly answered 2/4, 2014 at 0:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.