2013-08-23 3 views
1

Я пытаюсь разобрать строку в плоский список в TCL.tcl: описать строку в списке

Строка имеет формат

name1='value1',name2='value2',name3='value3' 

Я интересно, если есть способ, чтобы захватить имена и значения в список, который выглядит следующим образом:

{name1 value1 name2 value2 name3 value3} 

Обратите внимание, что имя или само по себе может содержать все, что включает в себя такие символы, как ' или = или ,

+0

Как бы вы быть уверены, что строка будет правильно разобран в списке? – Jerry

+0

Под моим комментарием я имею в виду, откуда вы знаете, какое имя и значение в строке, например: 'name1, name1cont = 'name1cont', = 'value1', value1cont. = 'Value1cont.'', где имя и значения могут содержать любые '' ',' = 'или', '? – Jerry

+1

Итак, 'name1 = 'value1', name2 = 'value2', name3 = 'value3'' имеет ключ' name1' со значением 'value1', name2 = 'value2', name3 = 'value3'? –

ответ

2

хорошо, возможно

set data {name1='value1',name2='value2',name3='value3'} 
foreach {- key value -} [regexp -all -inline {(.*?)='(.*?)'(,|$)} $data] { 
    lappend result $key $value 
} 

Примечание: Если ключ происходит только один раз, я предлагаю использовать dicts (dict set result $key $value).

+0

Спасибо, человек, это работает. Но я не совсем понимаю '' 'inside' (. *?)'. –

+1

Не жадные. Не пытайтесь сопоставить как можно больше символов, иначе вы получите что-то вроде 'name1 = 'value1', name2 = 'value2', name3 =' as key и ''value3'' в качестве значения, что не то, что вы хотеть. –

0

Самый простой способ - заменить символы =, , и ' с пробелами:

% set s {name1='value1',name2='value2',name3='value3'} 
name1='value1',name2='value2',name3='value3' 

% set new_s [string map {"='" " " "'," " " "'" " "} $s] 
name1 value1 name2 value2 name3 value3 

string map принимает два параметра. Первый - это список старых-новых пар строк. Вторая - сама строка. По существу, string map будет искать старые строки и заменять их новыми. Например, он будет искать =' и заменяет (пробел).

Обновление

выше решение не предполагает никакого пространства в названиях или значений. Следующее решение будет работать для тех значений со встроенными пробелами:

% set s {name1='value1',name2='value 2',name3='value3'} 
name1='value1',name2='value2',name3='value3' 

% string map {"=" " " "'" {"} "," " "} $s 
name1 "value1" name2 "value 2" name3 "value3" 
+0

Я думаю, вы пропустили заметки о том, что ключ и значение могут также содержать '' '', 'или' = ' –

+0

Он будет разбит на вход, как' backslash = '\' 'или' {= 'curly''. – potrzebie

+0

Да. Я пропустил это. –

0

Вы можете сделать это с отрицательным символьного класса

set s {name1='value1',name2='value2',name3='value3'} 
set result [regexp -inline -all -- {[^=',]+} $s] 
+0

Нет. Это не сработает, если имя/значение содержит '=', '' 'или', ' –

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