(
            self,
            sent,  # 句子词组输入（分好词）
            output,  # 输出（defaultdict）
            in_start=0,  # 内部起点（函数内部使用）
            out_start=0,  # 外部起点，即sent对应原始输入的起始位置
            trie_dic={},  # 当前层级的用来查找的trie_dic
            matching=()  # 当前匹配情况
    )
查找原理：按照常规trie树的查找原则，
        但是每个单词有两个匹配可能：1.匹配单词本身；2.匹配占位符None。
        因此只好递归匹配。
查找原理：按照常规trie树的查找原则，
        但是每个单词有两个匹配可能：1.匹配单词本身；2.匹配占位符None。
        因此只好递归匹配。
查找原理：按照常规trie树的查找原则， 但是每个单词有两个匹配可能：1 . 匹配单词本身；2 . 匹配占位符None。 因此只好递归匹配。
def _search(
            self,
            sent,  # 句子词组输入（分好词）
            output,  # 输出（defaultdict）
            in_start=0,  # 内部起点（函数内部使用）
            out_start=0,  # 外部起点，即sent对应原始输入的起始位置
            trie_dic={},  # 当前层级的用来查找的trie_dic
            matching=()  # 当前匹配情况
    ):
        """查找原理：按照常规trie树的查找原则，
        但是每个单词有两个匹配可能：1.匹配单词本身；2.匹配占位符None。
        因此只好递归匹配。
        """
        if sent:
            c = sent[0]
            if c in trie_dic:  # 匹配上当前词
                matching_ = matching + (out_start + in_start,
                                        )  # 将词添加到匹配tuple中
                # out_start+in_start
                # 为词在原句子中的实际下标
                if self.end in trie_dic[c]:  # 如果完整匹配一个模版
                    output[out_start, out_start + in_start + 1][
                        matching_] = trie_dic[c][self.end][1]  # 添加到output
                self._search(
                    sent[1:],
                    output,
                    in_start + 1,
                    out_start,
                    trie_dic[c],
                    matching=matching_)  # 递归查找

            if None in trie_dic:  # 匹配上占位符，不需要修改matching
                if self.end in trie_dic[None]:  # 如果完整匹配一个模版
                    output[out_start, out_start + in_start + 1][
                        matching] = trie_dic[None][self.end][1]  # 添加到output
                self._search(
                    sent[1:],
                    output,
                    in_start + 1,
                    out_start,
                    trie_dic[None],
                    matching=matching)  # 递归查找

            # 重点！！！
            # 连续几个词都可以匹配上占位符，但形式上只算一个。
            # 反过来说，就是前面已经匹配了一个占位符，后面可以反复匹配占位符，trie_dic不用递归
            if (not matching  # matching为空，即为起点
                    or matching[-1] != out_start + in_start  # 这意味着前面匹配了占位符
                ):
                if self.end in trie_dic:  # 如果完整匹配一个模版
                    output[out_start, out_start + in_start + 1][
                        matching] = trie_dic[self.end][1]
                self._search(
                    sent[1:],
                    output,
                    in_start + 1,
                    out_start,
                    trie_dic,  # trie_dic不用递归，因为多个占位符也算一个
                    matching=matching)
def _search ( self , sent , # 句子词组输入（分好词） output , # 输出（defaultdict） in_start = 0 , # 内部起点（函数内部使用） out_start = 0 , # 外部起点，即sent对应原始输入的起始位置 trie_dic = { } , # 当前层级的用来查找的trie_dic matching = ( ) # 当前匹配情况 ) : if sent : c = sent [ 0 ] if c in trie_dic : # 匹配上当前词 matching_ = matching + ( out_start + in_start , ) # 将词添加到匹配tuple中 # out_start+in_start # 为词在原句子中的实际下标 if self . end in trie_dic [ c ] : # 如果完整匹配一个模版 output [ out_start , out_start + in_start + 1 ] [ matching_ ] = trie_dic [ c ] [ self . end ] [ 1 ] # 添加到output self . _search ( sent [ 1 : ] , output , in_start + 1 , out_start , trie_dic [ c ] , matching = matching_ ) # 递归查找 if None in trie_dic : # 匹配上占位符，不需要修改matching if self . end in trie_dic [ None ] : # 如果完整匹配一个模版 output [ out_start , out_start + in_start + 1 ] [ matching ] = trie_dic [ None ] [ self . end ] [ 1 ] # 添加到output self . _search ( sent [ 1 : ] , output , in_start + 1 , out_start , trie_dic [ None ] , matching = matching ) # 递归查找 # 重点！！！ # 连续几个词都可以匹配上占位符，但形式上只算一个。 # 反过来说，就是前面已经匹配了一个占位符，后面可以反复匹配占位符，trie_dic不用递归 if ( not matching # matching为空，即为起点 or matching [ - 1 ] != out_start + in_start # 这意味着前面匹配了占位符 ) : if self . end in trie_dic : # 如果完整匹配一个模版 output [ out_start , out_start + in_start + 1 ] [ matching ] = trie_dic [ self . end ] [ 1 ] self . _search ( sent [ 1 : ] , output , in_start + 1 , out_start , trie_dic , # trie_dic不用递归，因为多个占位符也算一个 matching = matching )