Python正则表达式匹配除最后一个出现的所有内容

13

我有一个表达式,例如"./folder/thisisa.test/file.cxx.h",如何替换或删除除最后一个点以外的所有点?


我放的那个更快。不过你可能看不出区别。 - Loamhoof
最好使用循环将它们全部替换,跟踪最后一次替换的索引,并在循环后将最后一个点替换回去,这样可能会更快。 - didierc
如果你正在操作路径名,请看一下 os.path - Felipe
3个回答

21

使用正则表达式匹配除最后一个点外的所有内容:

'\.(?=[^.]*\.)'

使用先行断言来检查我们找到的点后面是否还有另一个点(先行断言不是匹配的一部分)。


2

使用 str.countstr.replace,无需正则表达式:

最初的回答:

s = "./folder/thisisa.test/file.cxx.h" 
s.replace('.', '', s.count('.')-1)
# '/folder/thisisatest/filecxx.h'

1

具体的单字符解决方案

在您目前的情况下,您可以使用

text = re.sub(r'\.(?![^.]*$)', '', text)

在这里,\.(?![^.]*$)可以匹配一个带有\..,它不是紧随着((?!...))除了.以外的任何0个或多个字符(参见[^.]*),一直到字符串结尾($)。
请参见正则表达式演示Python演示1个或多个字符的通用解决方案 如果您想替换.并且还要替换更多字符,可以使用一个围绕需要匹配的字符和一个正向先行断言.*及对捕获值的反向引用的字符类捕获组。
例如,您需要删除最后一个出现的[]^\/-.,您可以使用
([][^\\./-])(?=.*\1)

查看正则表达式演示

细节

  • ([][^\\./-]) - 一个捕获组,匹配][^\./-(注意这些字符的顺序很重要:-必须在最后,]必须在开头,^不应该在开头,\必须转义)
  • (?=.*\1) - 正向先行断言,需要任意0+个字符尽可能多地匹配,然后是捕获组1中捕获的值。

Python样例代码

import re
text = r"./[\folder]/this-is-a.test/fi^le.cxx.LAST[]^\/-.h"
text = re.sub(r'([][^\\./-])(?=.*\1)', '', text, flags=re.S)
print(text)

请注意字符串字面值中的r前缀。请注意,flags=re.S将使.匹配任何换行符序列。

1
两个明确的解决方案,我认为他的答案没有任何问题。+1 - The fourth bird

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