類似屬性檔案那樣, 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
其實,逗号和空格同作為分隔字元,語義上還有其他差别,一般情況下,逗号的語義更多:前面必須有有效詞,後面也必須有詞 ,這裡沒有強制這一層語義。