如何获取到特定子目录的路径?

2024-04-18 17:40:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我想要达到的目标

给定一个路径,我需要提取路径中位于指定子目录(如果存在)之前的部分—我们将称之为stopper,以便在这个问题中轻松识别它。你知道吗

应注意,路径可以以止动块开始或结束

一些输入/输出示例对:

path = 'some/path/to/my/file.ext'

# ends with stopper
stopper = 'my'
result = 'some/path/to'

# begins with stopper
stopper = 'some'
result = ''

# stopper in middle
stopper = 'to'
result = 'some/path'
# special case - should stop at first stopper location
path = 'path/to/to/my/file.ext'
stopper = 'to'
result = 'path'

到目前为止我所拥有的

我设计了两种获得答案的方法:

正则表达式

import re

# p = path; s = stopper
def regex_method(p,s):
  regex = r"(?:(?!(?:^|(?<=/))" + s + r").)+(?=/)"
  m = re.match(regex, p)
  if m:
    return m.group()
  return ''

这是可行的,但根据通过的止动块值,很容易出现故障-不适合在生产中使用。你知道吗

操作系统

import os

# p = path; s = stopper
def os_method(p,s):
  parts = os.path.dirname(p).split('/')
  return '/'.join(parts[:parts.index(s)])

这一点很有效,似乎比regex的对应项更简洁,但我觉得奇怪的是,我需要拆分字符串,然后根据值的索引拆分列表,然后将其连接在一起。我觉得这个可以简化或者改进。你知道吗


我的问题

  1. 有没有更惯用的方法来拆分特定目录名上的路径?你知道吗
  2. 有没有一个简单的方法来实现这一点使用列表理解?你知道吗

Tags: topath方法路径returnosmywith
3条回答

可以在生成器上使用^{}模块和next,如下所示:

from pathlib import Path

# p = path; s = stopper
def get_path(p,s):
    return next((parent for parent in Path(p).parents if not any(x in str(parent) for x in (f'/{s}/', f'{s}/', f'/{s}')) and str(parent) != s), '')

path = 'some/path/to/my/file.ext'
# ends with stopper
stopper = 'to' 

print(get_path(path, stopper))
# some/path

我建议使用pathlib

def split_path(path, stopper):
    parts = path.parts
    idx = next((idx for idx, part in enumerate(parts) if part == stopper))
    result = Path(*parts[:idx])
    return result

以您的例子:

path = Path('some/path/to/my/file.ext'

stopper = 'my'
split_path(path, stopper)

输出:PosixPath('some/path/to')

stopper = 'some'
split_path(path, stopper)

输出:PosixPath('.')

stopper = 'to'
split_path(path, stopper)

输出:PosixPath('some/path')

另一种似乎更有效、更简单的方法是使用^{},它(从文档中)生成一个迭代器,只要谓词为true,它就从iterable返回元素:

import os
from itertools import takewhile

def it_method(p, s):
  return '/'.join(takewhile(lambda d : d != s, p.split('/')))

测试:

print(it_method('some/path/to/my/file.ext', 'my'))
print(it_method('some/path/to/my/file.ext', 'to'))
print(it_method('some/path/to/my/file.ext', 'some'))
print(it_method('some/path/to/to/my/file.ext', 'to'))

输出:

some/path/to
some/path

some/path

因此在本例中,它会一直生成目录名,直到遇到stopper。你知道吗

谓词也可以缩短为s.__ne__,而不是使用lambda函数:

def it_method(p,s):
  return '/'.join(takewhile(s.__ne__, p.split('/')))

相关问题 更多 >