正则表达式在末尾修复(所有匹配项或无匹配项)为 1

rv7*_*rv7 2 ruby python regex substitution regex-greedy

我试图解决.在最后只有一个字符串中。例如,

line = "python...is...fun..."
Run Code Online (Sandbox Code Playgroud)

我有\.*$Ruby 中的正则表达式,它将被替换为单个.,就像在这个演示中一样,它似乎没有按预期工作。我搜索过类似的帖子,我得到的最接近的是Python 中的这个答案,它暗示了以下内容,

>>> text1 = 'python...is...fun...'
>>> new_text = re.sub(r"\.+$", ".", text1)
>>> 'python...is...fun.'
Run Code Online (Sandbox Code Playgroud)

但是,如果我.最后没有,它就会失败。所以,我已经试过像\b\.*$,因为在这里看到,但这未能对具有一定第三测试?在结束的。

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


预期输出:

python...is...fun.
python...is...fun.
python...is...fun??.
Run Code Online (Sandbox Code Playgroud)

The*_*ird 5

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

在替换中使用一个点。

(?:\.{2,}|(?<!\.))$
Run Code Online (Sandbox Code Playgroud)

解释

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

正则表达式演示| Python 演示

例如

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)
Run Code Online (Sandbox Code Playgroud)

输出

python...is...fun.
python...is...fun.
python...is...fun??.
Run Code Online (Sandbox Code Playgroud)

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

(?:\.{2,}|(?<=[^\s.]))$
Run Code Online (Sandbox Code Playgroud)

正则表达式演示