2013-10-28 3 views
2

Есть ли способ разделить строки и сохранить в списке? Как разбить строку и сохранить в два списка Например, у меня есть строка, где я разделить несколько строку с =:Как разбить строку и сохранить в списке через TCL

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

, а затем я хочу, чтобы создать два списка, как этот [a,b,c,d] и [1,2,3,4]:

+0

* a = 1, b = 2, c = 3, d = 4 * - одна строка? – jkshah

+0

да, но между ними нет запятой, и все они находятся в новой строке, например, a = 1 в новой строке b = 2 и т. Д. – user2901871

ответ

3

простой способ может быть с помощью цикла:

% 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 

Если вы не против регулярных выражений, вы можете попробовать что-то вроде этого:

% 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 
1

Пусть говорят ваши строки помещаются в файл abc.txt в следующем порядке

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

Вам нужно создать 2 списка, один для чисел и один для персонажей:

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 
5

Самый простой способ - прочитать все данные в, split в строках, а затем использовать regexp с каждой строкой для извлечения фрагментов.

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, что (при условии, что имя файла правильно), и вы получите выход как:

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

Сбор двух списков, как это не может быть самое лучшее, что делать с такими вещи. Часто, это лучше вместо того, чтобы хранить в массиве:

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

Как это, вы можете сделать Lookups от имени, вместо того, чтобы вручную искать. Предполагая, что ключи уникальны, порядок не имеет значения.

+0

+1 для массивов. используйте ['parray'] (http://tcl.tk/man/tcl8.5/TclCmd/library.htm), чтобы проверить его. –

0

Это довольно старый, но я бы сделал это по-другому ... Что-то вроде следующего, учитывая, что строка [a = 1 \ nb = 1 \ n ... и т. Д.] С именем переменной " 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} 

Возможно, только личное предпочтение, но для меня это кажется самым простым; код не был протестирован, но он похож на то, над чем я только что работал.

0

При замене знака равенства символов в $data с пробелами всегда оставляет правильное, даже однозначную список (как в приведенном выше примере) это можно сделать намного проще:

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

Документация: dict, set, string

Смежные вопросы