天天看點

key-value pair清單parser

類似屬性檔案那樣, 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

其實,逗号和空格同作為分隔字元,語義上還有其他差别,一般情況下,逗号的語義更多:前面必須有有效詞,後面也必須有詞 ,這裡沒有強制這一層語義。

繼續閱讀