深入解析 RecursiveCharacterTextSplitter 类
在自然语言处理和文本处理任务中,文本分割是一个常见的需求。文本分割的目的是将长文本分割成更小的、更易于处理的片段。RecursiveCharacterTextSplitter
类是一个强大的工具,它通过递归地尝试不同的分隔符来分割文本。本文将深入探讨这个类的实现细节,并通过代码示例帮助你更好地理解其工作原理。
前置知识
在深入探讨 RecursiveCharacterTextSplitter
类之前,我们需要了解一些基本概念:
- 文本分割:将长文本分割成更小的片段,以便于处理和分析。
- 分隔符:用于分割文本的字符或字符串。
- 递归:一种编程技术,函数调用自身来解决问题。
- 正则表达式:一种用于匹配字符串的模式。
类定义
RecursiveCharacterTextSplitter
类继承自 TextSplitter
类,并提供了递归分割文本的功能。
class RecursiveCharacterTextSplitter(TextSplitter):
"""Splitting text by recursively look at characters.
Recursively tries to split by different characters to find one
that works.
"""
初始化方法
类的初始化方法 __init__
接受几个参数:
separators
:一个可选的分隔符列表,默认为["\n\n", "\n", " ", ""]
。keep_separator
:一个布尔值或字符串,表示是否保留分隔符,默认为True
。is_separator_regex
:一个布尔值,表示分隔符是否为正则表达式,默认为False
。**kwargs
:其他关键字参数。
def __init__(
self,
separators: Optional[List[str]] = None,
keep_separator: Union[bool, Literal["start", "end"]] = True,
is_separator_regex: bool = False,
**kwargs: Any,
) -> None:
"""Create a new TextSplitter."""
super().__init__(keep_separator=keep_separator, **kwargs)
self._separators = separators or ["\n\n", "\n", " ", ""]
self._is_separator_regex = is_separator_regex
核心方法:_split_text
_split_text
方法是递归分割文本的核心。它接受两个参数:
text
:要分割的文本。separators
:当前使用的分隔符列表。
def _split_text(self, text: str, separators: List[str]) -> List[str]:
"""Split incoming text and return chunks."""
final_chunks = []
# Get appropriate separator to use
separator = separators[-1]
new_separators = []
for i, _s in enumerate(separators):
_separator = _s if self._is_separator_regex else re.escape(_s)
if _s == "":
separator = _s
break
if re.search(_separator, text):
separator = _s
new_separators = separators[i + 1 :]
break
_separator = separator if self._is_separator_regex else re.escape(separator)
splits = _split_text_with_regex(text, _separator, self._keep_separator)
# Now go merging things, recursively splitting longer texts.
_good_splits = []
_separator = "" if self._keep_separator else separator
for s in splits:
if self._length_function(s) < self._chunk_size:
_good_splits.append(s)
else:
if _good_splits:
merged_text = self._merge_splits(_good_splits, _separator)
final_chunks.extend(merged_text)
_good_splits = []
if not new_separators:
final_chunks.append(s)
else:
other_info = self._split_text(s, new_separators)
final_chunks.extend(other_info)
if _good_splits:
merged_text = self._merge_splits(_good_splits, _separator)
final_chunks.extend(merged_text)
return final_chunks
详细解析
-
选择合适的分隔符:
- 遍历分隔符列表,找到第一个在文本中出现的分隔符。
- 如果分隔符是正则表达式,则使用原始分隔符;否则,使用转义后的分隔符。
-
分割文本:
- 使用选定的分隔符分割文本。
- 如果分隔符为空字符串,则直接分割成单个字符。
-
递归分割:
- 对于每个分割后的片段,如果长度小于
_chunk_size
,则加入_good_splits
列表。 - 如果长度大于
_chunk_size
,则递归调用_split_text
方法继续分割。
- 对于每个分割后的片段,如果长度小于
-
合并片段:
- 将
_good_splits
列表中的片段合并,并加入final_chunks
列表。 - 如果
_good_splits
不为空,则合并并加入final_chunks
列表。
- 将
公开方法:split_text
split_text
方法是一个公开方法,调用 _split_text
方法并传入初始的分隔符列表。
def split_text(self, text: str) -> List[str]:
return self._split_text(text, self._separators)
示例代码
以下是一个使用 RecursiveCharacterTextSplitter
类的示例代码:
from typing import List
class TextSplitter:
def __init__(self, keep_separator: Union[bool, Literal["start", "end"]], **kwargs: Any) -> None:
self._keep_separator = keep_separator
self._chunk_size = kwargs.get("chunk_size", 1000)
self._length_function = kwargs.get("length_function", len)
def _merge_splits(self, splits: List[str], separator: str) -> List[str]:
# 合并片段的逻辑
pass
def _split_text_with_regex(text: str, separator: str, keep_separator: bool) -> List[str]:
# 使用正则表达式分割文本的逻辑
pass
# 示例使用
text = "这是一个示例文本。我们使用递归字符文本分割器来分割它。"
splitter = RecursiveCharacterTextSplitter(separators=["。", ",", " "])
chunks = splitter.split_text(text)
print(chunks)
总结
RecursiveCharacterTextSplitter
类通过递归地尝试不同的分隔符来分割文本,提供了灵活且强大的文本分割功能。通过本文的讲解和示例代码,希望你能够更好地理解和应用这个类,从而在文本处理任务中更加高效地工作。