Редактировать : поскольку модуль csv
не работает должным образом с кавычками внутри полей, для реализации этой функции требуется немного больше работы:
import re
quoted = re.compile(r'"[^"]*"')
class QuoteSaver(object):
def __init__(self):
self.saver = dict()
self.reverser = dict()
def preserve(self, mo):
s = mo.group()
if s not in self.saver:
self.saver[s] = '"%d"' % len(self.saver)
self.reverser[self.saver[s]] = s
return self.saver[s]
def expand(self, mo):
return self.reverser[mo.group()]
x = 'name="John Smith", age=34, height=173.2, location="US", avatar=":,=)"'
qs = QuoteSaver()
y = quoted.sub(qs.preserve, x)
kvs_strings = y.split(',')
kvs_pairs = [kv.split('=') for kv in kvs_strings]
kvs_restored = [(k, quoted.sub(qs.expand, v)) for k, v in kvs_pairs]
def converter(v):
if v.startswith('"'): return v.strip('"')
try: return int(v)
except ValueError: return float(v)
thedict = dict((k.strip(), converter(v)) for k, v in kvs_restored)
for k in thedict:
print "%-8s %s" % (k, thedict[k])
print thedict
Я излучаю thedict
дважды, чтобы точно показать, как и почему он отличается от требуемого результата; вывод:
age 34
location US
name John Smith
avatar :,=)
height 173.2
{'age': 34, 'location': 'US', 'name': 'John Smith', 'avatar': ':,=)',
'height': 173.19999999999999}
Как вы видите, выход для значения с плавающей запятой такой же, как запрашиваемый при прямом излучении с print
, но это не так, и не может быть (так как IS нет Значение с плавающей запятой, которое будет отображать 173.2
в таком случае! -), когда print
применяется ко всему dict
(потому что это неизбежно использует repr
для ключей и значений - и repr
из 173.2
имеет эту форму, учитывая обычные проблемы с тем, как значения с плавающей запятой хранятся в двоичном, а не в десятичном виде и т. Д. И т. Д.). Я мог бы определить подкласс dict
, который переопределяет __str__
на специальные значения с плавающей запятой, если это действительно требуется.
Но, я надеюсь, что это отвлечение не мешает основной идее - до тех пор, пока двойные кавычки правильно сбалансированы (и нет двойных кавычек внутри двойных кавычек), этот код выполняет требуемую задачу сохранения "специального символы "(в данном случае запятые и знаки равенства) взяты в обычном смысле, когда они находятся в двойных кавычках, даже если двойные кавычки начинаются с внутри " поля ", а не с начала поле (csv
имеет дело только с последним условием). Вставьте несколько промежуточных оттисков, если способ работы кода неочевиден - сначала он превращает все «поля в двойных кавычках» в особо простую форму ("0"
, "1"
и т. Д.), Одновременно записывая то, что является фактическим содержимым соответствующие этим простым формам; в конце простые формы возвращаются в исходное содержание. Обрезка в двойных кавычках (для строк) и преобразование строк без кавычек в целые числа или числа с плавающей запятой, наконец, обрабатываются простой функцией converter
.