You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现QlockTwo时钟:忽略终端颜色按可见字符拆分字符串

解决带ANSI颜色控制字符的字符串拆分问题

要实现仅按可见字符拆分且保留颜色效果,关键是忽略ANSI控制字符的长度计数,同时跟踪颜色状态确保拆分后的子串颜色显示正常。

核心思路

  1. 识别ANSI控制字符:这类字符以\033[开头、m结尾,属于不可见的格式控制序列,不参与可见字符计数。
  2. 遍历字符串时分离两类字符:控制字符仅记录当前颜色状态,不纳入计数;可见字符单独统计长度。
  3. 达到指定拆分长度时截断字符串,确保截断点前后的颜色控制序列完整,拆分后的子串继承正确的颜色状态。

实现代码

import re

def split_colored_string(s, chunk_size):
    # 匹配ANSI颜色控制序列的正则表达式
    ansi_pattern = re.compile(r'\033\[[0-9;]*m')
    chunks = []
    current_chunk = []
    visible_count = 0
    current_ansi = []  # 记录当前生效的颜色控制序列

    # 拆分字符串为控制序列和可见文本的交替列表
    text_parts = ansi_pattern.split(s)
    ansi_matches = ansi_pattern.findall(s)
    elements = []
    for i in range(len(text_parts)):
        if text_parts[i]:
            elements.append(('text', text_parts[i]))
        if i < len(ansi_matches):
            elements.append(('ansi', ansi_matches[i]))
            current_ansi.append(ansi_matches[i])

    for elem_type, content in elements:
        if elem_type == 'ansi':
            current_chunk.append(content)
        else:
            remaining = chunk_size - visible_count
            if len(content) <= remaining:
                current_chunk.append(content)
                visible_count += len(content)
                if visible_count == chunk_size:
                    chunks.append(''.join(current_chunk))
                    current_chunk = current_ansi.copy()  # 继承当前颜色
                    visible_count = 0
            else:
                # 填充当前块剩余容量
                current_chunk.append(content[:remaining])
                visible_count += remaining
                chunks.append(''.join(current_chunk))
                # 拆分剩余文本,每块都带上当前颜色
                remaining_text = content[remaining:]
                while len(remaining_text) > chunk_size:
                    chunks.append(''.join(current_ansi + [remaining_text[:chunk_size]]))
                    remaining_text = remaining_text[chunk_size:]
                # 初始化新块
                current_chunk = current_ansi.copy() + [remaining_text]
                visible_count = len(remaining_text)
    # 处理最后未完成的块
    if current_chunk:
        chunks.append(''.join(current_chunk))
    return chunks

# 测试示例
colored_text = "\033[92mHELLO WORLD\033[0m THIS IS A TEST\033[91m WITH COLORS\033[0m"
split_result = split_colored_string(colored_text, 10)
for chunk in split_result:
    print(chunk)

代码说明

  • 用正则分离控制序列和可见文本,确保计数仅针对可见字符。
  • 跟踪当前生效的颜色控制序列,拆分后的子串自动继承颜色,避免颜色中断。
  • 处理文本拆分时优先填满当前块剩余容量,剩余部分按指定长度拆分并保留颜色。

内容的提问来源于stack exchange,提问作者pwrljzkkdup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:01:04