Langchain-Chatchat/markdown_docs/text_splitter/chinese_recursive_text_spli...

8.7 KiB
Raw Blame History

FunctionDef _split_text_with_regex_from_end(text, separator, keep_separator)

_split_text_with_regex_from_end: 该函数的功能是使用正则表达式从文本末尾开始分割文本。

参数:

  • text: 需要被分割的文本类型为str。
  • separator: 用作分割符的正则表达式类型为str。
  • keep_separator: 一个布尔值,指示是否保留分隔符在返回的列表中。

代码描述: 此函数接受一个字符串text和一个正则表达式separator作为参数,以及一个布尔值keep_separator,用于控制分割后是否保留分隔符。如果separator不为空,函数将根据separator分割文本。如果keep_separator为真,则分隔符也会被保留在返回的列表中。这是通过将文本与分隔符一起分割,然后将分割后的文本和分隔符重新组合成新的列表项来实现的。如果分割后的列表长度为奇数,表示最后一个元素后没有分隔符,这时会将最后一个元素添加到结果列表中。如果keep_separator为假,则简单地根据分隔符分割文本,不保留分隔符。如果separator为空,则将文本分割成单个字符的列表。最后,函数返回一个列表,包含非空的分割结果。

在项目中,这个函数被ChineseRecursiveTextSplitter类的_split_text方法调用。_split_text方法用于递归地分割文本,根据一系列分隔符逐步将文本分割成更小的块。_split_text_with_regex_from_end函数在这个过程中负责使用正则表达式从文本末尾开始进行分割,这是实现文本递归分割的关键步骤之一。通过调整keep_separator参数,可以灵活控制分隔符在分割结果中的保留情况,这对于保持文本的原始结构信息是非常有用的。

注意:

  • 确保传入的separator是有效的正则表达式,否则re.split可能无法正确执行分割操作。
  • 如果文本非常长,使用复杂的正则表达式作为分隔符可能会影响性能。

输出示例: 假设有以下调用:

_split_text_with_regex_from_end("hello,world,this,is,a,test", ",", True)

可能的返回值为:

["hello,", "world,", "this,", "is,", "a,", "test"]

在这个示例中,文本被逗号分割,并且每个分割后的部分都保留了逗号。

ClassDef ChineseRecursiveTextSplitter

ChineseRecursiveTextSplitter: 该类的功能是对中文文本进行递归分割。

属性:

  • separators: 分隔符列表,用于指定文本分割的规则。
  • keep_separator: 布尔值,指定在分割后的文本中是否保留分隔符。
  • is_separator_regex: 布尔值,指定分隔符列表中的元素是否为正则表达式。

代码描述: ChineseRecursiveTextSplitter类继承自RecursiveCharacterTextSplitter专门用于处理中文文本的递归分割。它允许用户自定义分隔符列表以及控制是否保留分隔符和分隔符是否按正则表达式处理。默认的分隔符列表包括常见的中文和英文句子结束符号如句号、问号、感叹号等。此类通过递归调用_split_text方法,能够有效地将长文本分割成更小的片段,同时保证分割后的文本片段不会过长或过短,适合进一步的文本处理或分析。

在分割文本时,_split_text方法首先确定使用的分隔符,然后根据这个分隔符将文本分割成小片段。如果某个片段长度超过预设的阈值,该方法会递归地对该片段进行进一步分割,直到所有片段的长度都符合要求。最终,方法返回一个经过清理(去除多余的换行符和空白字符)的文本片段列表。

注意:

  • 在使用自定义分隔符时,如果is_separator_regex设置为False,则需要确保分隔符列表中的元素不包含任何正则表达式特殊字符,或者使用re.escape进行转义。
  • 该类适用于处理中文文本,但也支持包含英文句子的文本分割,通过提供适当的分隔符列表可以灵活应对不同的文本分割需求。

输出示例:

text_splitter = ChineseRecursiveTextSplitter()
text = "这是一个测试文本。包含多个句子!还有英文句子. Yes, it works well."
split_texts = text_splitter.split(text)
# 输出可能为: ['这是一个测试文本。', '包含多个句子!', '还有英文句子.', 'Yes, it works well.']

在此示例中,split方法将输入的文本根据中文和英文的句子结束符号进行分割返回一个包含四个独立句子的列表。这显示了ChineseRecursiveTextSplitter类在处理混合语言文本时的灵活性和有效性。

FunctionDef init(self, separators, keep_separator, is_separator_regex)

init: 该函数的功能是创建一个新的文本分割器。

参数:

  • separators: 可选参数,类型为List[str]。用于指定分割文本的分隔符列表。如果未提供,则使用默认分隔符列表。
  • keep_separator: 布尔类型参数,默认值为True。指定在分割文本后,是否保留分隔符。
  • is_separator_regex: 布尔类型参数,默认值为True。指定分隔符列表中的分隔符是否应被视为正则表达式。
  • kwargs: 接收任意额外的关键字参数,这些参数将被传递给父类的初始化方法。

代码描述: 此函数是ChineseRecursiveTextSplitter类的构造函数,用于初始化一个文本分割器实例。它首先调用父类的初始化方法,传递keep_separator和任何其他关键字参数(**kwargs)。然后,它根据提供的参数初始化内部变量。如果separators参数未提供,将使用一个默认的分隔符列表,该列表包括常见的中文和英文句子结束符号,如句号、问号、感叹号及其各自的空格组合形式,以及中文的逗号和分号。_is_separator_regex变量用于标记分隔符列表中的元素是否应被视为正则表达式,以便在分割文本时使用。

注意:

  • 在使用默认分隔符时,由于包含正则表达式,可以匹配多种常见的句子结束符号及其后的空格,这对于处理包含多种标点符号的文本非常有用。
  • 如果选择不保留分隔符(keep_separator=False),则分割后的文本将不包含任何分隔符。这可能对某些需要精确控制输出格式的应用场景有影响。
  • is_separator_regex设置为False时,分隔符列表中的字符串将被直接用作分割文本的依据,而不是作为正则表达式解析,这在处理非常特定的分隔符需求时可能更为有用。

FunctionDef _split_text(self, text, separators)

_split_text: 该函数的功能是根据一系列分隔符递归地分割文本,并返回分割后的文本块列表。

参数:

  • text: 需要被分割的文本类型为str。
  • separators: 用于分割文本的分隔符列表类型为List[str]。

代码描述: _split_text函数首先确定使用哪个分隔符来分割文本。它通过遍历separators列表并检查每个分隔符是否存在于文本中来实现。一旦找到第一个匹配的分隔符,函数就使用这个分隔符来分割文本,并将后续的分隔符列表更新为新的new_separators列表,用于后续的递归分割。

分割文本的实际操作是通过调用_split_text_with_regex_from_end函数完成的,该函数使用正则表达式从文本末尾开始分割文本。这一步骤允许保留或移除分隔符,具体取决于_keep_separator的值。

接下来,函数会检查分割后的每个文本块的长度。如果文本块的长度小于设定的_chunk_size,则将其添加到结果列表中。对于长度超过_chunk_size的文本块,函数会尝试使用new_separators列表中的下一个分隔符递归地分割这些文本块。

最后,函数返回一个经过清理的文本块列表,其中移除了所有空白文本块,并将连续的换行符替换为单个换行符。

注意:

  • 确保separators列表中的分隔符是有效的,且按照从最优先到最不优先的顺序排列。
  • 函数内部使用正则表达式进行文本分割,因此分隔符需要是有效的正则表达式,或者在不使用正则表达式分割时,分隔符将被自动转义。
  • 递归分割可能会导致大量的函数调用,特别是在处理大型文本或复杂的分隔符模式时,应注意性能和栈溢出的风险。

输出示例: 假设有以下调用:

_split_text("这是一个测试文本。这还是一个测试文本!", ["。", ""])

可能的返回值为:

["这是一个测试文本", "这还是一个测试文本"]

在这个示例中,文本被"。"和""分隔符分割,每个分割后的部分都是独立的文本块。