如何在字符串的标点符号两侧插入空格?求正则实现方案
问题描述
我有如下格式的字符串: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
相关产品推荐
相关产品推荐

