Python实现QlockTwo时钟:忽略终端颜色按可见字符拆分字符串
解决带ANSI颜色控制字符的字符串拆分问题
要实现仅按可见字符拆分且保留颜色效果,关键是忽略ANSI控制字符的长度计数,同时跟踪颜色状态确保拆分后的子串颜色显示正常。
核心思路
- 识别ANSI控制字符:这类字符以
\033[开头、m结尾,属于不可见的格式控制序列,不参与可见字符计数。 - 遍历字符串时分离两类字符:控制字符仅记录当前颜色状态,不纳入计数;可见字符单独统计长度。
- 达到指定拆分长度时截断字符串,确保截断点前后的颜色控制序列完整,拆分后的子串继承正确的颜色状态。
实现代码
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
相关产品推荐
相关产品推荐

