将长文本拆分为两个或多个部分,每个部分的最大长度为 python

Split a long text in two or more parts each one with a maximum length in python

假设我有一个长文本,我想用 API 处理一个允许的最大字符数 (N)。我想将该文本拆分为 2 个或多个短于 N 个字符的文本,并基于分隔符。我知道我可以按分隔符拆分,但我希望输出的子文本数量尽可能少。

例如,假设我的文字是:

“让痛苦本身成为一种痛苦,因为讨厌向它致敬,对你们两个我们的雪貂。我出于仇恨而拥有它,这样,我就不应该把它们生给希腊人。但是“我的乐趣。他们认为与专业人士没有退缩,我会拒绝批评没有。”让它成为一场比赛。

问题不包括时间,只有错误vim和。让它成为你的一个愉快的选择,让它看起来你被推翻了,你很难固执和正确。我的足球会告诉其他人。他已经习惯了等待折磨,而你是享乐之王,旗手。"

长度为 550 个字符。假设 N 为 250。我希望文本以这种方式拆分:

问题不包括时间,只有错误vim和。让它成为你的一个愉快的选择,让它看起来你被推翻了,你很难固执和正确。我的足球会告诉其他人。”(232 个字符)

知道如何在 Python 中执行此操作吗?

感谢您的帮助。 弗朗西斯卡


n = 250
text = """Lorem ipsum dolor sit amet, odio salutandi id nam, ferri nostro te duo. Eum ex odio habeo qualisque, ne eos natum graeco. Autem voluptatum ex mea. Nulla putent reformidans cu pro, posse recusabo reprehendunt pro no. An sit ludus oblique. Consulatu cotidieque ex sea, nam no duis prompta expetendis.

Est ne tempor quaestio complectitur, modo error vim et. Option voluptaria efficiantur te eam, ea appareat evertitur qui, te vix pertinax recteque. Mea eu diceret ceteros. Expetenda torquatos assueverit est ex, te reque voluptatibus signiferumque has."""

if len(text) >= 550:
  print(text[0:n-1])
  print(text[n:])
else:
  print(text)

所以你可以有一个长度为 n 的变量(在你的例子中是 250)。然后它检查文本的长度是否大于或等于 550 个字符。如果是,它将打印从 char 0 到长度 n 的所有内容(减去 1,因此您得到的是前 250 个字符,而不是前 251 个字符)。那么第二部分就是这样做:从n到最后。

您可以使用正则表达式来做到这一点:

import re


ouput = re.findall(r".{1,250}(?:\.|$)", data)
print(ouput)

  • .{1,250}:匹配1到250次之间的任意字符,越多越好。
  • \.: 匹配一个点。
  • |: 或者
  • $:匹配字符串的结尾。

您也可以将分隔符和最大长度放在变量中。

import re


num_max = 250
delimiter = re.escape('.')

ouput = re.findall(fr".{{1,{num_max}}}(?:{delimiter}|$)", data)
print(ouput)

输出:

[
    'Lorem ipsum dolor sit amet, odio salutandi id nam, ferri nostro te duo. Eum ex odio habeo qualisque, ne eos natum graeco. Autem voluptatum ex mea. Nulla putent reformidans cu pro, posse recusabo reprehendunt pro no. An sit ludus oblique.',
    ' Consulatu cotidieque ex sea, nam no duis prompta expetendis.',
    'Est ne tempor quaestio complectitur, modo error vim et. Option voluptaria efficiantur te eam, ea appareat evertitur qui, te vix pertinax recteque. Mea eu diceret ceteros. Expetenda torquatos assueverit est ex, te reque voluptatibus signiferumque has.'
]

您可以创建一个函数,它可以 return 所需长度的块。

In [13]: def split(N, text):
    ...:     chunks = [text[i:i+N] for i in range(0, len(text), N-1)]
    ...:     return chunks

这将return 列表格式的块。即

text = "Lorem.................." # complete lorem ispm
chunks = split(250, text)
print(len(s[0]), len(s[1]), len(s[2]))

输出长度为

250 250 50

这是一个可能的解决方案:

def split_txt(txt, sep, n):
    if any(len(s) + 1 > n for s in txt.split(sep)):
        raise Exception('The text cannot be split')
    result = []
    start = 0
    while start + n <= len(txt):
        result.append(txt[start:start + n].rsplit(sep, 1)[0] + sep)
        start += len(result[-1])
    if start < len(txt):
        result.append(txt[start:])
    return result
        

您可以考虑使用其他答案见解构建 built-in TextWrapper 工具的子 class。 Base class 允许您指定处理文本的规则:最大列数(宽度)、最大行数、连字符的处理等。

The textwrap module provides some convenience functions, as well as TextWrapper, the class that does all the work. If you’re just wrapping or filling one or two text strings, the convenience functions should be good enough; otherwise, you should use an instance of TextWrapper for efficiency. [emphasis mine]

基本的 class 本身并没有处理 OP 问题的具体细节,但是对于任何登陆此页面的人来说都值得一看。

这部分的东西也可以给一些启发:https://docs.python.org/3/library/text.html#stringservices