提问人:HappyPy 提问时间:12/3/2014 最后编辑:HappyPy 更新时间:2/2/2023 访问量:46012
替换部分路径 - Python
replace part of path - python
问:
有没有一种快速方法可以替换 python 中的部分路径?
例如:
old_path='/abc/dfg/ghi/f.txt'
我不知道路径()的开头,所以我真正想告诉python保留后面的所有内容(包括),并将之前的所有内容替换为:/abc/dfg/
/ghi/
/ghi/
/jkl/mno/
>>> new_path
'/jkl/mno/ghi/f.txt/'
答:
16赞
Cory Kramer
12/3/2014
#1
>>> import os.path
>>> old_path='/abc/dfg/ghi/f.txt'
首先使用 os.path.relpath
从您选择的起始目录中获取相对路径
>>> rel = os.path.relpath(old_path, '/abc/dfg/')
>>> rel
'ghi\\f.txt'
然后使用 os.path.join
将路径的新第一部分添加到此相对路径
>>> new_path = os.path.join('jkl\mno', rel)
>>> new_path
'jkl\\mno\\ghi\\f.txt'
评论
1赞
HappyPy
12/3/2014
对不起,忘了提我不知道路径的起点是什么,所以理想情况下,我希望能够告诉 python 只选择从 /ghi/ 开始的路径部分,并用 /jkl/mno/ 替换之前的任何内容。这在某种程度上可能吗?
0赞
Cory Kramer
12/3/2014
不过,这可能是模棱两可的,如果您有并想从 开始,那会怎样?你至少知道你想走多远吗?就像它总是从文件位置向上一个文件夹吗?foo/bar/foo/folder/f.txt
foo
foo
0赞
HappyPy
12/3/2014
是的,我确定路径中没有重复的文件夹名称。所以,这将是一种分裂。我希望python从'/ghi/'(在我的示例中是/ghi/f.txt)中选择所有内容,并用/jkl/mno/替换之前的任何内容。
0赞
Diogo Santiago
2/18/2023
混合和 .只需使用一个并坚持下去。os
pathlib
30赞
abarnert
12/3/2014
#2
如果您使用的是 Python 3.4+,或者愿意安装向后移植,请考虑使用 pathlib
而不是:os.path
path = pathlib.Path(old_path)
index = path.parts.index('ghi')
new_path = pathlib.Path('/jkl/mno').joinpath(*path.parts[index:])
如果你只想坚持使用 2.7 或 3.3 stdlib,没有直接的方法可以做到这一点,但你可以通过循环获得等效的 .例如,保留每个路径组件,直到找到第一个,然后附加新前缀,将替换最后一个之前的所有内容(如果您想替换第一个之前的所有内容,更改内容并不难):parts
os.path.split
ghi
ghi
ghi
path = old_path
new_path = ''
while True:
path, base = os.path.split(path)
new_path = os.path.join(base, new_path)
if base == 'ghi':
break
new_path = os.path.join('/jkl/mno', new_path)
这有点笨拙,所以你可能需要考虑编写一个简单的函数,给你一个路径组件的列表或元组,这样你就可以只使用 ,然后将它们重新连接在一起,就像版本一样。find
pathlib
评论
0赞
HappyPy
12/3/2014
pathlib 看起来很棒,假设 Python 2.7 中没有等效项?
0赞
abarnert
12/3/2014
@HappyPy:是的,有。不是在 stdlib 中,但是,就像 3.x 的许多新功能一样,PyPI 上有一个半官方的向后移植,它具有 2.x 中有意义的所有功能。 (我相信这意味着除了在 Unix 上转换为基于语言环境的字节名称和 Windows 上的 Unicode str 名称之外的所有内容;相反,你只是在两个平台上得到普通的未指定的 str。
0赞
klaas
10/10/2016
对于 python >3.4:您必须执行一个示例的第一行应该是:而不是 .因为它的引用方式如下列所示。[顺便说一句:这个例子帮了大忙!import pathlib
p = pathlib.Path(old_path)
path = pathlib.Path(old_path)
p
9赞
Padraic Cunningham
12/3/2014
#3
您可以使用以下索引:ghi
old_path.replace(old_path[:old_path.index("ghi")],"/jkl/mno/")
In [4]: old_path.replace(old_path[:old_path.index("ghi")],"/jkl/mno/" )
Out[4]: '/jkl/mno/ghi/f.txt'
评论
2赞
The Data Scientician
6/27/2018
我没有投反对票,但这不是一个很好的答案。如果序列“ghi”在前缀中重复怎么办?例如,它不适用于 .先拆分成几个部分可能会更好。/fooghi/bar/ghi/baz
0赞
Padraic Cunningham
6/27/2018
@TheDataScientician,OP 想要替换路径中的完整目录,即 .替换目录名称中的子字符串是另一回事。/ghi/
2赞
Jon Clements
12/3/2014
#4
一种相当幼稚的方法,但可以完成工作:
功能:
def replace_path(path, frm, to):
pre, match, post = path.rpartition(frm)
return ''.join((to if match else pre, match, post))
例:
>>> s = '/abc/dfg/ghi/f.txt'
>>> replace_path(s, '/ghi/', '/jkl/mno')
'/jkl/mno/ghi/f.txt'
>>> replace_path(s, '/whatever/', '/jkl/mno')
'/abc/dfg/ghi/f.txt'
4赞
normanius
1/21/2023
#5
当您想要替换路径中的某些已知基目录时,以下内容非常有用。
from pathlib import Path
old_path = Path('/abc/dfg/ghi/f.txt')
old_root = Path('/abc/dfg')
new_root = Path('/jkl/mno')
new_path = new_root / old_path.relative_to(old_root)
# Result: /jkl/mno/ghi/f.txt
据我所知,OP特别提到基本目录的路径是未知的。但是,由于删除基本目录的路径是一项常见任务,并且问题的标题(“替换路径的一部分”)肯定会将一些人带到这里,因此我还是要发布它。
评论
1赞
ojdo
4/27/2023
就是这样。(我知道,不是针对发布的 Q,而是针对大多数知道的人。old_root
0赞
Psionman
2/2/2023
#6
我需要替换路径中任意数量的任意字符串 例如,将 'package' 替换为 foo in
VERSION_FILE = Path(f'{Path.home()}', 'projects', 'package', 'package', '_version.py')
所以我使用这个电话
_replace_path_text(VERSION_FILE, 'package', 'foo)
def _replace_path_text(path, text, replacement):
parts = list(path.parts)
new_parts = [part.replace(text, replacement) for part in parts]
return Path(*new_parts)
评论