正则表达式将文件路径分成组?

Regex to split file paths into groups?

这是文件的结构:

(number)/firstdirectory/unimportant/unimportant/lastdirectory.DAT

我需要编写一个正则表达式,将编号、第一个目录和最后一个目录分别放入第 1、2 和 3 组中。

其他文件示例(我用来测试的文件):

(1)/Downloads/Maps/Map of Places.pdf
(25)/Publications/1995Publications.pdf
(31)/Table-of-Contents.pdf

这是我的:

import re

reggie = r"^.* \(([0-9]*)\)(.*)\/([^\/]*)\.(.*)$"


with open('test2.txt') as f:
    lines = f.readlines()

for line in lines:
    match = re.search(reggie, line)
    if match:
        num = match.group(1)
        sub = match.group(2)
        file = match.group(3)
        print(num, sub, file)

我希望得到的是:

    1 Downloads Map of Places
    25 Publications 1995Publications
    31 Table-of-Contents (assumes theres no first directory and just takes the last)

我最终得到的是:

    1 /Downloads/Maps Map of Places
    25 /Publications 1963Publications
    31  Table of Contents

非常接近,唯一的问题是,当目录超过2个时,中间的目录包含在第一个目录中,并且在第一个目录之前有不必要的正斜杠。

我已经考虑这个问题几个小时了,我被难住了。我最好的尝试是在数字后强制使用正斜杠以删除输出中不需要的内容,然后在第一个目录之后添加一个可选的,以防目录超过 2 个。

像这样:

    reggie = r"^.*\(([0-9]*)\)\/(.*)\/*([^\/]*)\.(.*)$"

但是这样一来,所有的目录都合并成了一个,没有最后一个目录了。

任何帮助将不胜感激,这似乎是一个简单的解决方案,但我一定是看错了。

首先正则表达式不是要走的路。应该改用 Pathlib。

这里是正则表达式解决方案,如果您仍然希望使用它的话:

import re
regex = re.compile(r"\((\d+)\)(?:/([^/]+))?.*/([^\.]+)\..*$")
paths = ["(1)/Downloads/Maps/Map of Places.pdf","(25)/Publications/1995Publications.pdf","(31)/Table-of-Contents.pdf"]
for path in paths:
    print(regex.match(path).groups())

输出:

('1', 'Downloads', 'Map of Places')
('25', 'Publications', '1995Publications')
('31', None, 'Table-of-Contents')

您应该使用 Pathlib 而不是使用正则表达式。更可靠,支持不同的操作系统:

import pathlib
paths = ["(1)/Downloads/Maps/Map of Places.pdf","(25)/Publications/1995Publications.pdf","(31)/Table-of-Contents.pdf"]
for path in map(pathlib.PurePath, paths):  # Convert all paths to PurePaths
    path_parts = path.parts
    number = path_parts[0]
    filename = path.stem
    root_directory = path_parts[1] if len(path_parts) > 2 else None
    print((number, root_directory, filename))

输出:

('(1)', 'Downloads', 'Map of Places')
('(25)', 'Publications', '1995Publications')
('(31)', None, 'Table-of-Contents')