Python如何为字符串中指定索引区间的子串添加<span>标签
字符串指定区间添加span标签的简洁实现
问题场景
给定原始字符串和若干子串的索引起止区间,需要给对应区间内的子串包裹<span>标签,区间不需要对齐词边界,可以是任意合法的字符串索引范围。
示例输入输出
基础输入:
s = "there is wall E on the way" spans = [(0,5), (9,13), (16,18)]
对应输出:
<span>there</span> is <span>wall</span> E <span>on</span> the way
其他测试场景:
- 跳过中间区间场景
输入:spans = [(0,5), (16,18)]
输出:<span>there</span> is wall E <span>on</span> the way - 跨词区间场景
输入:spans = [(0,5), (16,22)]
输出:<span>there</span> is wall E <span>on the</span> way - 非词边界切割场景
输入:spans = [(0,11), (16,22)]
输出:<span>there is wa</span>ll E <span>on the</span> way
提问者原本的实现思路是逐段切割未标记内容、包裹标签片段后追加到列表再拼接,代码里还存在变量名笔误(误用未定义的x代替output),想要更简洁、不需要反复写列表追加的实现方式。原实现代码如下:
s = "there is wall E on the way" spans = [(0,5), (9,13), (16,18)] output = [] start, end = 0, 0 for sp in spans: start = sp[0] x.append(s[end:start]) end = sp[1] x.append(f'<span>{s[start:end]}</span>') x.append(s[end:]) output = "".join(x)
实现方案
最简洁的原生Python实现不需要引入额外依赖,只需要把片段收集逻辑简化即可,代码量和逻辑都更清晰:
def add_span_tags(s: str, spans: list[tuple[int, int]]) -> str: # 预处理:如果spans可能乱序,先按起始位置排序 spans.sort() res_parts = [] last_pos = 0 for start, end in spans: # 追加当前区间前的未标记文本 res_parts.append(s[last_pos:start]) # 追加包裹标签的区间文本 res_parts.append(f'<span>{s[start:end]}</span>') last_pos = end # 追加最后一个区间后的剩余文本 res_parts.append(s[last_pos:]) return ''.join(res_parts)
如果想要更紧凑的写法,也可以统一处理所有切割点,省去手动维护位置变量的步骤:
def add_span_tags(s: str, spans: list[tuple[int, int]]) -> str: spans.sort() # 拼接所有切割点:起始位置0、所有区间起止点、字符串末尾位置 cuts = [0] for sp in spans: cuts.extend(sp) cuts.append(len(s)) parts = [] for i in range(0, len(cuts), 2): l, r = cuts[i], cuts[i+1] segment = s[l:r] # 非末尾段的区间需要包裹标签 if i < len(cuts) - 2: segment = f'<span>{segment}</span>' parts.append(segment) return ''.join(parts)
两种实现的时间复杂度都是O(n)(n为字符串长度),和原实现效率一致,代码更整洁易读,也能覆盖所有测试场景。
注意:如果传入的span区间存在重叠,需要提前做区间合并处理,否则会出现标签嵌套错误。
内容的提问来源于stack exchange,提问作者alvas
相关产品推荐
相关产品推荐

