我们说我有两个路径名: head 和 tail 。它们可以与任意数量的段重叠。如果他们不想正常加入他们。如果它们重叠,我想检测公共部分并相应地组合它们。更具体一点:如果名称中有重复,我希望找到尽可能长的重叠部分。实施例
"/root/d1/d2/d1/d2" + "d2/d1/d2/file.txt" == "/root/d1/d2/d1/d2/file.txt"
and not "/root/d1/d2/d1/d2/d1/d2/file.txt"
这种情况下是否有任何现成的库函数,或者我必须实现一个?
答案 0 :(得分:4)
您可以在join
函数中使用列表推导:
>>> p1="/root/d1/d2/d1/d2"
>>> p2="d2/d1/d2/file.txt"
>>> p1+'/'+'/'.join([i for i in p2.split('/') if i not in p1.split('/')])
'/root/d1/d2/d1/d2/file.txt'
如果差异只是第二个路径的基本名称,您可以使用os.path.basename
获取bname并将其连接到p1
:
>>> import os
>>> p1+'/'+os.path.basename(p2)
'/root/d1/d2/d1/d2/file.txt'
答案 1 :(得分:3)
我建议您使用difflib.SequenceMatcher后跟get_matching_blocks
>>> p1, p2 = "/root/d1/d2/d1/d2","d2/d1/d2/file.txt"
>>> sm = difflib.SequenceMatcher(None,p1, p2)
>>> size = sm.get_matching_blocks()[0].size
>>> path = p1 + p2[size:]
>>> path
'/root/d1/d2/d1/d2/file.txt'
解答一般解决方案
def join_overlapping_path(p1, p2):
sm = difflib.SequenceMatcher(None,p1, p2)
p1i, p2i, size = sm.get_matching_blocks()[0]
if not p1i or not p2i: None
p1, p2 = (p1, p2) if p2i == 0 else (p2, p1)
size = sm.get_matching_blocks()[0].size
return p1 + p2[size:]
执行
>>> join_overlapping_path(p1, p2)
'/root/d1/d2/d1/d2/file.txt'
>>> join_overlapping_path(p2, p1)
'/root/d1/d2/d1/d2/file.txt'
答案 2 :(得分:1)
我认为这有效:
p1 = "/root/d1/d2/d1/d2"
p2 = "d2/d1/d2/file.txt"
def find_joined_path(p1, p2):
for i in range(len(p1)):
if p1[i:] == p2[:len(p1) - i]:
return p1[:i] + p2
print(find_joined_path(p1, p2))
请注意,这是一个适用于任何两个字符串的通用解决方案,因此它可能不像仅适用于文件路径的解决方案那样优化。
答案 3 :(得分:0)
我只是在这里寻找答案。希望它可以帮助其他人。
这是我在Nodejs中做到的方式
const path1 = '/root/user/name/code/website/'
const path2 = './website/index.js'
const arrOfDirectories = [...path1.split('/'), ...path2.split('/')]
// ['', 'root', 'user', 'name', 'code', 'website', '', '.' 'website', 'index.js']
const arrOfUniqueDirectories = arrOfDirectories.filter((value, index, self) => self.indexOf(value) === index)
// ['', 'root', 'user', 'name', 'code', 'website', '', '.','index.js']
const jankyPath = arrOfUniqueDirectories.join('/')
// /root/user/name/code/website./index.js
const myPath = path.normalize(jankyPath)
// myPath = /root/user/name/code/website/index.js