我使用RegEx搜索包含文件路径列表的多行字符串。
目标是:如果匹配在文件夹名中-只返回此文件夹路径(如果它们匹配,不要返回任何子文件夹)。如果匹配位于文件名中,则返回整行(完整文件路径)。
当前使用的模式返回整个字符串:.*([^\\]*(John|Smith|Junior)){2}.*
期望返回的字符串:
C:\temp\John Smith Junior\file.pdf -> C:\temp\John Smith Junior\
C:\temp\John Smith Junior\John Smith Junior\file.pdf -> C:\temp\John Smith Junior\
C:\temp\John Smith Junior file.pdf -> C:\temp\John Smith Junior file.pdf我试着添加到模式的末尾,比如:\n或(\n)或(?!=.+),但这并不完全符合我的要求。谢谢你的帮助!
演示:https://regex101.com/r/98d6Ed/1
.*([^\\]*(John|Smith|Junior)){2}.*发布于 2021-10-11 15:41:56
使用(John|Smith|Junior)是一个替代方案--约翰、史密斯或朱尼尔。
如果您想要匹配整个字符串John Smith Junior,可以在模式中使用它。
在Python少年中,您可以使用一个if子句来测试第一次出现re之后的\。
如果它在那里,那么就是匹配,否则匹配除\以外的任何字符,直到字符串结束。
^.*?\bJunior\b(\\)?(?(1)|.*)^开始.*?\bJunior\b匹配青少年第一次发病(\\)?可选择地捕获第1组中的\(?(1)|.*)条件,使用(?(1)测试组1是否存在,即匹配,否则使用.*匹配字符串的其余部分。import re
strings = [
r"C:\temp\John Smith Junior\file.pdf",
r"C:\temp\John Smith Junior\John Smith Junior\file.pdf",
r"C:\temp\John Smith Junior file.pdf"
]
for s in strings:
m = re.match(r".*?\bJunior\b(\\)?(?(1)|.*)", s)
if m:
print(m.group())输出
C:\temp\John Smith Junior\
C:\temp\John Smith Junior\
C:\temp\John Smith Junior file.pdf另一个选项,匹配至少2倍交替中的一个名称,然后匹配除换行符或反斜杠以外的任何字符:
^.*?\\[^\\\n]*\b(?:John|Smith|Junior)\s+(?:John|Smith|Junior)\b[^\\\n]*发布于 2021-10-11 16:09:47
我建议不要使用regexp,只需使用优秀的pathlib类即可。
from pathlib import PureWindowsPath
lines = [
r"C:\temp\John Smith Junior\file.pdf",
r"C:\temp\John Smith Junior\John Smith Junior\file.pdf",
r"C:\temp\John Smith Junior file.pdf"
]
def first_match(path, parts):
for parent in reversed(path.parents):
if any(part in str(parent) for part in parts):
return parent
return None
for line in lines:
path = PureWindowsPath(line)
parts = ('John', 'Smith', 'Junior')
directory_match = first_match(path, parts)
if directory_match:
print(directory_match)
else:
if any(part in path.name for part in parts):
print(path)第三种选择是使用pathlib将部件解析为目录和文件名,如上面所示,然后使用regexp进行匹配,例如简单地使用(John|Smith|Junior)。
https://stackoverflow.com/questions/69528803
复制相似问题