简易Parser入门【二】:解析简单的字符串,括号套括号形式

简易Parser入门【二】:解析简单的字符串,括号套括号形式

abcd(awef(af)(32d)(sdf(sdf)))

我们希望遇到括号就做成list嵌套list的形式。一个办法是一个一个字符遍历,但值得注意的是,字符串里边英文字母和数字不是固定长度的,后面遇到复杂的解析还得考虑数字、空格、换行等复杂情况,这给我们带来困扰。所以,我们应该考虑先把字符串进行分词,变成如下的形式:

["abcd", "(", "awef", "(", "af", ")", "(", "32d", ")", "(", "sdf", "(", "sdf", ")", ")"]

这样分词以后,list里边就是一个一个元素单元,再进行遍历就方便很多。所以,我们如何构造一个这样的分词器呢?它将不同单词隔开的依据是什么?当然是因为它们不属于一个元素。在这里,问题较为简单,不同元素之间是通过)和(号进行隔开的,我们只需要遇到这2个符号进行分隔就OK了。分隔字符串一般是从起始位置到结束位置,例如abcd是从0分割点到4号分割点(即str[0:4]),而第一个(号是从4号到5号分割点(即str[4:5]),具体可以用下图表示:

整个字符串我们都要遍历,那么肯定有一个for循环。在循环中,我们很容易得到当前位置i,假设循环到str[4] == "(",那么我们应该分割str[0:4],而循环到str[5] == "a"的时候,我们应该分割str[4:5]。现在我们可以初步构建这个循环:

    def parse_go(str_in):
        search_dict = {"(": "left",
                       ")": "right"}
        save_list = []
        pos = 0
        last_state = search_dict.get(str_in[0], "En")
        for i, c in enumerate(str_in):
            curr_state = search_dict.get(c, "En")
            if curr_state != last_state:
                save_list.append((str_in[self.pos:i], last_state))
                pos = i
                last_state = curr_state
        return save_list