正则表达式:在匹配的字符串中添加字符

10

我有一个长字符串是一个段落,但是句号后面没有空格。例如:

para = "I saw this film about 20 years ago and remember it as being particularly nasty. I believe it is based on a true incident: a young man breaks into a nurses\' home and rapes, tortures and kills various women.It is in black and white but saves the colour for one shocking shot.At the end the film seems to be trying to make some political statement but it just comes across as confused and obscene.Avoid."
我尝试使用 re.sub 解决这个问题,但输出的结果与我预期的不同。
这是我的做法:

我正在尝试使用 re.sub 来解决此问题,但输出结果并非我所期望的。

这是我所做的:

re.sub("(?<=\.).", " \1", para)

我正在匹配每个句子的第一个字符,并希望在其前面放置一个空格。我的匹配模式是(?<=\.).,它(据说)检查出现在句点后面的任何字符。我从其他stackoverflow问题中学到,\1匹配上次匹配的模式,因此我将替换模式写成\1,一个空格后跟先前匹配的字符串。

以下是输出:

"I saw this film about 20 years ago and remember it as being particularly nasty. \x01I believe it is based on a true incident: a young man breaks into a nurses\' home and rapes, tortures and kills various women. \x01t is in black and white but saves the colour for one shocking shot. \x01t the end the film seems to be trying to make some political statement but it just comes across as confused and obscene. \x01void. \x01

与其匹配任何在点号之前的字符并在其前添加空格,re.sub\x01 替换了匹配的字符。为什么?如何在匹配的字符串前添加字符?


1
https://dev59.com/KGcs5IYBdhLWcg3ww2tP#12597709 - Millie Smith
1
我认为问题应该是这样说的:“但是在某些句点后面没有空格。”因为第一个句点后面有空格。 - Sash Sinha
@shash678 是的,你说得对。我没有提到这个因为在我的情况下,有多个空格是可以的,而且我不想让问题变得复杂。 - versatile parsley
总有一个简单的方法:text = text.replace(".", ". ").replace(". " + " ", ". ")(字符串连接是因为Stack Exchange会吃掉双空格)。基本上,将每个句号替换为句号+空格,将每个句号+空格+空格替换为句号+单空格。不需要正则表达式,也不需要导入任何东西。 - Fake Name
5个回答

9
< p > (?<=a)b正向后发。它匹配跟在 a 后面的 ba 不会被捕获。所以在你的表达式中,我不确定在这种情况下 \1 的值是什么,但它不是 (?<=...) 中的内容。

你当前的方法还有一个缺陷:即使已经存在空格,它也会在 . 后面添加一个空格。

为了在 . 后添加丢失的空格,我建议采用不同的策略:用 . 和一个空格替换 .-后跟非空格-非点号

re.sub(r'\.(?=[^ .])', '. ', para)

你的方法好多了!只需要匹配一个字符就能降低复杂度。它成功了,谢谢 :) - versatile parsley
你不打算用“……”替换成“...”吗? - Alberto Santini
@AlbertoSantini 感谢您的发现,已经进行了更新以防止这种情况,谢谢! - janos

2
您可以使用以下正则表达式(带有正向回顾和负向先行断言):

你可以使用以下的正则表达式(带有正向回顾负向先行断言):

(?<=\.)(?!\s)

Python
re.sub(r"(?<=\.)(?!\s)", " ", para)

看见 演示

2
您的正则表达式稍作修改也可以使用:
print re.sub(r"([\.])([^\s])", r"\1 \2", para)

# I saw this film about 20 years ago and remember it as being particularly nasty. I believe it is based on a true incident: a young man breaks into a nurses' home and rapes, tortures and kills various women. It is in black and white but saves the colour for one shocking shot. At the end the film seems to be trying to make some political statement but it just comes across as confused and obscene. Avoid.

1
更简单的方法:re.sub(r"\.(\S)", r". \1", para)。避免使用look around,加一分。 - jpmc26

1
我觉得这就是你想要做的。你可以传入一个函数来进行替换。
import re

def my_replace(match):
    return " " + match.group()

my_string = "dhd.hd hd hs fjs.hello"
print(re.sub(r'(?<=\.).', my_replace, my_string))

输出:

dhd. hd hd hs fjs. hello

正如@Seanny123指出的那样,即使句号后面已经有空格,这也会添加一个空格。

3
如果已经存在空格,则此答案会添加一个空格。 - Seanny123
@seanny123,OP称“句号后没有空格”。我们可以整天争论需求。我正在使用手机,不会费力来完善这个。只是不要点赞并继续前进,伙计。 - Millie Smith
抱歉,关于语气和内容。我试图提供信息,但搞砸了。我的错。 - Seanny123
@seanny123 哥们儿,你说得对。我只是有点累了,而且用手机回复有点困难。我会在我的答案中加入你的评论,因为它是有价值的信息。 - Millie Smith
@Seanny123 是正确的,而且这个解决方案是有效的,因为在这种情况下,我可以接受多个空格。如果我们要稍微概括一下这个解决方案,那么我们需要注意额外的空格。 - versatile parsley

0

你可以使用最简单的正则表达式替换:

re.sub(r'\.(?=\w)', '. ', para)

它只是匹配每个句号,并使用前瞻,(?=\w) 确保下一个字符是单词字符,而不是句号后面已经有空格,并将其替换为 .


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接