类似属性文件那样, key1 = value1, key = value2
简练的算法,只区分word字符和分隔字符(空格, tab, 逗号,=等等),不需要处理key和vaue的分隔符(=)。就是parse word,tokenize,分词驱动,分出一个词来做什么操作的问题,就是考虑一点,作为key还是value。用一个key变量记录状态就好了,key是空则当前word是key, key有值,则当前word是value。key和value总是交替出现的。
def parseKVPairs(s):
wordStart, key, sep, result = -1, '', ' \t=,:', {}
for i in xrange(len(s)):
if s[i] not in sep:
if i == 0 or s[i - 1] in sep: wordStart = i
if i == len(s) - 1 or s[i + 1] in sep:
if key == '': key = s[wordStart: i + 1]
else:
result[key] = s[wordStart: i + 1]
key = ''
return result
print parseKVPairs("key = abc, key2 ; xyz , key3=kkk")
假如允许有些key没有value,那就得处理=或者:了,框架还是分词,多记录一个状态:处在key的范围还是value的范围,inValue == True表示在value的范围,否则在key的范围,初始为False,在key的范围。
def parseKVPairs(s):
wordStart, key, sep, inValue, result = -1, '', ' \t=,:', False, {}
for i in xrange(len(s)):
if s[i] not in sep:
if i == 0 or s[i - 1] in sep: wordStart = i
if i == len(s) - 1 or s[i + 1] in sep:
if not inValue:
if key != '': result[key] = ''
key = s[wordStart: i + 1]
else:
result[key] = s[wordStart: i + 1]
inValue, key = False, ''
elif s[i] in ':=': inValue = True
return result
print parseKVPairs("key = abc, key2, key3 = v3")
这里逗号,空格,tab完全是一样的,只用于分词。等号(或冒号)除了用于分词,还触发key scope 到 value scope的切换,之后分出一个词fulfill value后,scope切换回key
其实,逗号和空格同作为分隔字符,语义上还有其他差别,一般情况下,逗号的语义更多:前面必须有有效词,后面也必须有词 ,这里没有强制这一层语义。