簡體   English   中英

如何獲取到特定子目錄的路徑?

[英]How to get the path up to a specific sub-directory?

我正在努力實現的目標

給定路徑,我需要提取路徑中專門命名的子目錄(如果存在)之前的部分-在此問題中,我們將其稱為“ 塞子”以輕松識別它。

應當注意,路徑可以以塞子開始或結束

用於輸入/輸出的一些樣本對:

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)])

這比正則表達式更有效,但似乎更簡潔,但是對我來說,我需要拆分字符串,然后基於值的索引列表,然后將其連接在一起,這似乎讓我感到奇怪。 我覺得這可以簡化或改進。


我的問題

  1. 是否有更慣用的方式在特定目錄名稱上分割路徑?
  2. 有沒有簡單的方法可以使用列表推導來實現?

另一個看似更有效,更簡單的方法是使用itertools.takewhile ,只要謂詞為true,它就會(從文檔中)使迭代器返回可迭代的元素:

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('/')))

我建議使用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')

您可以使用pathlib模塊和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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM