实现保留斜杠的Python路径规范化函数
实现保留原始斜杠的路径规范化函数
rawnorm 首先明确:Python标准库中没有直接满足需求的内置函数。os.path.normpath等路径处理工具会统一转换分隔符为系统默认类型(Windows用\,类Unix用/),无法保留原始路径中的混合斜杠。
实现思路
要同时完成路径规范化(合并连续斜杠、移除.、处理..)并保留原始斜杠类型,核心是:
- 拆分路径为根目录、组件和分隔符,保留分隔符的原始类型
- 用栈处理路径组件,移除
.并解析.. - 重新拼接处理后的组件与对应分隔符
代码实现
import re def rawnorm(path): # 提取根目录(适配Windows盘符、UNC路径和类Unix根路径) root = "" rest = path # 匹配Windows UNC路径(如\\server\share) unc_match = re.match(r'^\\\\[^\\/]+\\[^\\/]+(?=[\\/]|$)', path) if unc_match: root = unc_match.group() rest = path[len(root):] else: # 匹配Windows盘符路径(如C:\) drive_match = re.match(r'^[A-Za-z]:[\\/]', path) if drive_match: root = drive_match.group() rest = path[len(root):] else: # 匹配类Unix根路径(如/) if path.startswith('/'): root = '/' rest = path[1:] # 拆分剩余路径为组件和分隔符 parts = re.findall(r'([^\\/]+)|([\\/]+)', rest) components = [] separators = [] current_sep = None for comp, sep in parts: if sep: # 合并连续分隔符,保留原始类型(//→/,\\→\) current_sep = sep[0] elif comp: if comp == '.': continue # 忽略当前目录标记 if current_sep is not None: separators.append(current_sep) current_sep = None components.append(comp) # 用栈处理上级目录标记.. stack = [] sep_stack = [] for idx, comp in enumerate(components): if comp == '..': # 弹出上一级组件(根目录不能被弹出) if stack: stack.pop() if sep_stack: sep_stack.pop() else: stack.append(comp) if idx > 0: sep_stack.append(separators[idx-1]) # 拼接最终路径 result = root if stack: # 拼接第一个组件 if sep_stack: result += sep_stack[0] + stack[0] else: result += stack[0] # 拼接后续组件与分隔符 for sep, comp in zip(sep_stack[1:], stack[1:]): result += sep + comp # 保留原始路径结尾的分隔符(如果有) if rest and rest[-1] in ('\\', '/'): if not stack: if not root.endswith(('\\', '/')): result += rest[-1] else: result += rest[-1] return result
测试示例
# Windows路径测试 print(rawnorm(r"C:\foo/bar\..\baz")) # 输出: C:\foo/baz print(rawnorm(r"\\server\share//dir\../subdir")) # 输出: \\server\share/dir/subdir # 类Unix路径测试 print(rawnorm("/a//b/c/../d")) # 输出: /a/b/d print(rawnorm("x/y\../z")) # 输出: x/z
说明
- 该函数会保留原始路径中的
\和/,不会统一转换 - 自动合并连续斜杠(如
//→/,\\→\) - 正确处理
.(当前目录)和..(上级目录) - 适配Windows盘符、UNC路径和类Unix路径格式
内容的提问来源于stack exchange,提问作者kubinka0505
相关产品推荐
相关产品推荐

