首页 > 解决方案 > 当 Python 中有多个文件时,正则表达式替换字符串中的文件路径

问题描述

我很难找到一种方法来匹配字符串中的多个文件路径,同时保留字符串的其余部分。

编辑:忘记添加文件路径可能包含一个点,因此将“用户名”编辑为 user.name”

# filepath always starts with "file:///" and ends with file extension
text = """this is an example text extracted from file:///c:/users/user.name/download/temp/anecdote.pdf 
1 of 4 page and I also continue with more text from 
another path file:///c:/windows/system32/now with space in name/file (1232).html running out of text to write."""

我找到了许多可行的答案,但是当存在多个 filepath 时失败,并且还替换了两者之间的其他字符。

import re
fp_pattern = r"file:\/\/\/(\w|\W){1,255}\.[\w]{3,4}"
print(re.sub(fp_pattern, "*IGOTREPLACED*", text, flags=re.MULTILINE))

>>>"this is an example text extracted from *IGOTREPLACED* running out of text to write."

我也尝试过使用“在模式后找到空格后停止”,但我无法让一个工作:

fp_pattern = r"file:\/\/\/(\w|\W){1,255}\.[\w]{3,4} ([^\s]+)"
>>> 0 matches

标签: pythonregex

解决方案


请注意,这{1,255}是一个贪婪的量词,并且会匹配尽可能多的字符,您需要在?其后添加。

但是,仅使用惰性{1,255}?量词并不能解决问题。您需要定义比赛应该在哪里结束。当扩展名后面紧跟空格或字符串结尾时,您似乎只想匹配这些 URL。

因此,使用

fp_pattern = r"file:///.{1,255}?\.\w{3,4}(?!\S)"

查看正则表达式演示

如果在当前位置的(?!\S)右侧有一个非空白字符,则负前瞻将失败任何匹配。.{1,255}?将匹配任何 1 到 255 个字符,尽可能少。

在 Python 中用作

re.sub(fp_pattern, "*IGOTREPLACED*", text, flags=re.S)

( re.MULTILINE)re.M标志仅重新定义^和锚定行为,使它们匹配$的开始/结束而不是整个字符串。该标志允许匹配任何字符,包括换行符。re.S.

请不要使用(\w|\W){1,255}?, 使用.{1,255}?with re.Sflag 来匹配任何字符,否则性能会下降。


推荐阅读