正则表达式替换换行符为空格,除非与指定字符在同一单词中

-1 投票
2 回答
41 浏览
提问于 2025-04-14 17:42

假设我有一个包含多个换行符的字符串,比如:

string = '\nsetting1: short string\nsetting2: much longer string\nwith a newline in it\nsetting3: short string\n'

我需要一个正则表达式,用在re.sub()函数中,这个表达式只会匹配那些换行符不和冒号在同一个“词”里的情况。这样,下面的替换就会得到以下输出:

import re
re.sub(regex, ' ', string)

Out: '\nsetting1: short string\nsetting2: much longer string with a newline in it\nsetting3: short string '

我不知道怎么把“如果这个词里没有冒号”这部分翻译成正则表达式,有什么想法吗?谢谢

2 个回答

1

你可以从一个相关的匹配开始,这里是一个或多个字母数字字符后面跟着一个冒号。

然后你可以继续匹配一行或多行,这些行以一个或多个字母数字字符开头,但不以冒号结尾。

在这个匹配的基础上,你可以把换行符替换成空格。

^\w+:.*(?:\n\w+(?:[^\S\n].*)?)+$

这个模式匹配:

  • ^ 字符串的开始
  • \w+: 匹配一个或多个字母数字字符,后面跟着一个:
  • .* 匹配这一行的其余部分
  • (?: 不捕获的分组,用来整体重复
    • \n 匹配一个换行符
    • \w+ 匹配一个或多个字母数字字符
    • (?:[^\S\n].*)? 可选地匹配一个空格,后面跟着这一行的其余部分
  • )+ 关闭不捕获的分组,并重复1次或多次,以匹配至少2行内容
  • $ 字符串的结束

可以查看一个 正则表达式示例 和一个 Python示例

示例

import re

string = "\nsetting1: short string\nsetting2: much longer string\nwith a newline in it\nsetting3: short string\n"
result = re.sub(r"(?m)^\w+:.*(?:\n\w+(?:[^\S\n].*)?)+$", lambda m: m.group().replace('\n', ' '), string)
print(result)

输出

setting1: short string
setting2: much longer string with a newline in it
setting3: short string
2

你可以使用正则表达式来替换 \n(?!\w*:),这个表达式的意思是排除那些后面跟着可选单词并以冒号结尾的换行符。

inp = '\nsetting1: short string\nsetting2: much longer string\nwith a newline in it\nsetting3: short string\n'
output = re.sub(r'\n(?!\w*:)', ' ', inp)
print(output)

这样打印出来的结果是:

setting1: short string
setting2: much longer string with a newline in it
setting3: short string

撰写回答