【问题标题】:Regex add character to matched string正则表达式将字符添加到匹配的字符串
【发布时间】:2017-08-01 14:24:15
【问题描述】:

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

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("(?<=\.).", " \1", para)

我正在匹配每个句子的第一个字符,并且我想在它之前放置一个空格。我的匹配模式是(?&lt;=\.).,它(据说)检查一段时间后出现的任何字符。我从其他 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。为什么?如何在匹配的字符串前添加一个字符?

【问题讨论】:

  • 我认为问题应该是 “但是在 一些 个句点之后没有空格。” 因为在第一个句点之后有空格?
  • @shash678 是的,你是对的。我没有这么说,因为在我的情况下,可以有多个空格,我不想让问题变得复杂
  • 总是有便宜的答案:text = text.replace(".", ". ").replace(". " + " ", ". ")(字符串连接是因为堆栈交换占用了双倍空间)。基本上,用句点+空格替换每个句点,用句点+单个空格替换每个句点+空格+空格。不需要正则表达式,也不需要导入任何东西..

标签: python regex nlp


【解决方案1】:

(?&lt;=a)bpositive lookbehind。它匹配b 跟在a 之后。 a 未被捕获。所以在你的表达中,我不确定\1 的值在这种情况下代表什么,但它不是(?&lt;=...) 的内部。

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

要在. 之后添加 missing 空格,我建议采用不同的策略: 将 .-followed-by-non-space-non-dot 替换为 . 和一个空格:

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

【讨论】:

  • 你的方法好多了!它通过仅匹配一个字符来降低复杂性。成功了,谢谢:)
  • 你不打算这样把“...”换成“...”吗?
  • @AlbertoSantini 不错,已更新以防止出现这种情况,谢谢!
【解决方案2】:

您的regex 稍作修改的版本也可以使用:

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.

【讨论】:

  • 更简单:re.sub(r"\.(\S)", r". \1", para)。 +1 避免环顾四周。
【解决方案3】:

您也许可以使用以下正则表达式(带有positive look-behindnegative look-ahead 断言)

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

蟒蛇

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

demo

【讨论】:

    【解决方案4】:

    我认为这就是你想要做的。您可以传入一个函数来进行替换。

    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 指出的那样,即使句号之后已经有一个空格,这也会添加一个空格。

    【讨论】:

    • 如果已有空间,此答案会添加一个空间。
    • @seanny123 OP 声明“句号后没有空格”。我们可以整天争论需求。我正在打电话,不会费心去完善它。只是不要投票并继续前进,伙计。
    • 对不起,关于语气和内容。试图提供信息并且搞砸了。我的错。
    • @seanny123 不,伙计,你很好。你说得对。我只是累了,在手机上,所以很难输入有意义的回复。我会在我的回答中添加一篇文章,添加您的评论,因为它是有价值的信息。
    • @Seanny123 是正确的,这个解决方案是有效的,因为在这种情况下我可以使用多个空格。如果我们稍微概括一下这个解决方案,那么我们需要处理额外的空白。
    【解决方案5】:

    您可以使用的最简单的正则表达式替换是这个:

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

    它只是匹配每个句点,并使用前瞻,(?=\w) 来确保接下来有一个单词字符,并且句点后面还没有空格,并将其替换为 .

    【讨论】:

      猜你喜欢
      • 2021-06-30
      • 1970-01-01
      • 2022-01-17
      • 2012-06-05
      • 2013-12-25
      • 1970-01-01
      相关资源
      最近更新 更多