Python如何实现字符串按最大长度分块并在换行符处截断
Discord歌词Embed分页最优实现方案
你不需要手写反向步长的for循环做遍历搜索,Python内置的字符串方法就能极简实现需求,同时还能解决你原有方案里长词导致的字符超限问题。
原有方案的核心问题
- 按固定词数拆分没有对齐Discord的1024字符硬限制,遇到长单词很容易触发超限报错
- 无差别按词数切分会直接打断整句歌词,可读性很差
实现思路
直接用字符串内置的rfind()方法即可,这个方法原生支持从指定位置反向查找目标字符的索引,完全匹配「在最大长度范围内找最后一个换行符作为切点」的需求,不需要自己写循环:
- 把分页阈值直接设为字符数(建议设900~1000,给Embed的标题、页脚等内容留冗余,从根源避免超限)
- 每次截取剩余歌词的前
max_len长度片段,在片段内查找最后一个换行符位置 - 找到换行就以换行位置为切点拆分,没找到换行就退而找最近的空格拆分,极端无空格场景才硬切长度,避免死循环
可直接替换的实现代码
def split_lyrics(lyrics: str, max_len: int = 950) -> list[str]: pages = [] remaining = lyrics.strip() while remaining: # 剩余内容长度不超限制就直接作为最后一页 if len(remaining) <= max_len: pages.append(remaining) break # 优先找最大长度范围内的最后一个换行符 split_pos = remaining.rfind("\n", 0, max_len) # 找不到换行就找最近的空格,避免把单词截断 if split_pos == -1: split_pos = remaining.rfind(" ", 0, max_len) # 连空格都没有的极端超长内容,直接按最大长度硬切 if split_pos == -1: split_pos = max_len # 收集当前页,过滤空内容 cur_page = remaining[:split_pos].strip() if cur_page: pages.append(cur_page) # 截断剩余内容进入下一轮循环 remaining = remaining[split_pos:].strip() return pages # 替换原有create_embed里的分页逻辑即可 def create_embed(lyrics, song): lyric_pages = split_lyrics(lyrics) # 后续你的分页交互、Embed构造逻辑不需要改动 return lyric_pages
效果验证
用你举的示例测试:
测试文本:
Shadows fall over my heart\nI black out the moon\n,设置max_len=30(对应你示例里的截断长度场景)
拆分结果第一页为:Shadows fall over my heart,完全符合预期,不会把下一句的内容截断到上一页。
内容的提问来源于stack exchange,提问作者SBECK1
相关产品推荐
相关产品推荐

