正则表达式将(所有匹配项或 none)最后修复为一个

Regex to fix (all the matches or none) at the end to one

我正在尝试将最后的 . 修复为字符串中只有一个 。例如,

line = "python...is...fun..."

我在 Ruby 中有正则表达式 \.*$,它将被单个 . 替换,如 Python 中的 this demo, which don't seem to work as expected. I've searched for similar posts, and the closest I'd got is ,它建议如下,

>>> text1 = 'python...is...fun...'
>>> new_text = re.sub(r"\.+$", ".", text1)
>>> 'python...is...fun.'

但是,如果最后没有 .,它就会失败。所以,我试过 \b\.*$seen here,但是在第三次测试中失败了,最后有一些 ?

我的问题是,为什么 \.*$ 不匹配所有 .(尽管是贪婪的)以及如何正确做题?


预期输出:

python...is...fun.
python...is...fun.
python...is...fun??.

您可以使用交替匹配 2 个或更多点,或者断言直接在左边的不是 ! ? 或点本身之一。

在替换中使用一个点。

(?:\.{2,}|(?<!\.))$

说明

  • (?: 交替的非捕获组
    • \.{2,} 匹配 2 个或更多点
    • |
    • (?<!\.) 获取直接左边不是 . 的位置(可以根据需要扩展其他字符)
  • )关闭非捕获组
  • $ 字符串结尾(如果后面不能有换行符,则使用 \Z

Regex demo | Python demo

例如

import re 
strings = [
    "python...is...fun...",
    "python...is...fun",
    "python...is...fun??"
]

for s in strings:
    new_text = re.sub(r"(?:\.{2,}|(?<!\.))$", ".", s)
    print(new_text)

输出

python...is...fun.
python...is...fun.
python...is...fun??.

如果不应将空字符串替换为点,则可以使用正向后视。

(?:\.{2,}|(?<=[^\s.]))$

Regex demo