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

如何在字符串的标点符号两侧插入空格?求正则实现方案

问题描述

我有如下格式的字符串:hey what is up!、"what did you say?"、"he said 'well'"等,同时已定义分隔符正则表达式为:[!%&'()$#"\/\\*+,-.:;<=>?@\[\]^_´{|}~]`。我需要在这些分隔符的前后插入空格,最终效果如下:`"hey what is up !"`、`"what did you say ?"`、`"he said ' well '"`,即若分隔符前接其他非空格字符则在前加空格,若分隔符后接其他非空格字符则在后加空格。
我不想通过拆分分隔符的方式实现该需求,目前已写出遍历字符的解决方案,想了解如何通过正则实现。
现有实现代码如下:

space = set("[!%&'()$#\"/\*+,-.:;<=>?@[]^_´`{|}~]")
for sent in self.sentences:
    sent = list(sent)
    for i, char in enumerate(sent):
        # 索引时需注意不要超出字符串长度
        if i != 0:
            # 若当前字符是标点且前一位不是空格,在当前位置前插入空格
            if sent[i] in space and sent[i - 1] != " ":
                sent.insert(i, " ")
        if i != len(sent)-1:
            # 若当前字符是标点且后一位不是空格,在当前位置后插入空格
            if sent[i] in space and sent[i + 1] != " ":
                sent.insert(i + 1, " ")
正则实现方案

用正则的零宽断言可以直接匹配符合条件的位置插入空格,无需遍历字符,核心实现逻辑如下:

  • 匹配「分隔符前接非空格字符」的场景:用正向零宽后行断言(?<=\S)匹配非空格前缀,匹配到的分隔符前加空格
  • 匹配「分隔符后接非空格字符」的场景:用正向零宽先行断言(?=\S)匹配非空格后缀,匹配到的分隔符后加空格
    具体Python实现代码:
import re

# 分隔符正则,注意字符集合内的特殊字符转义
PUNCT_PATTERN = r"[!%&'()$#\"/\\*+,\-.:;<=>?@\[\]^_´`{|}~]"

def add_space_around_punct(sent):
    # 分隔符前接非空格字符时,前面加空格
    sent = re.sub(rf'(?<=\S)({PUNCT_PATTERN})', r' \1', sent)
    # 分隔符后接非空格字符时,后面加空格
    sent = re.sub(rf'({PUNCT_PATTERN})(?=\S)', r'\1 ', sent)
    return sent

# 测试示例
test_cases = [
    'hey what is up!',
    '"what did you say?"',
    '"he said \'well\'"'
]
for case in test_cases:
    print(add_space_around_punct(case))

运行输出和要求的目标效果完全匹配:

hey what is up !
" what did you say ? "
" he said ' well ' "

如果需要一次替换完成,也可以合并为单个正则规则:

def add_space_around_punct(sent):
    return re.sub(rf'(?<=\S)({PUNCT_PATTERN})|({PUNCT_PATTERN})(?=\S)', lambda m: f' {m.group()}' if m.group(1) else f'{m.group()} ', sent)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:06:00