You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现保留斜杠的Python路径规范化函数

实现保留原始斜杠的路径规范化函数rawnorm

首先明确:Python标准库中没有直接满足需求的内置函数。os.path.normpath等路径处理工具会统一转换分隔符为系统默认类型(Windows用\,类Unix用/),无法保留原始路径中的混合斜杠。

实现思路

要同时完成路径规范化(合并连续斜杠、移除.、处理..)并保留原始斜杠类型,核心是:

  1. 拆分路径为根目录、组件和分隔符,保留分隔符的原始类型
  2. 用栈处理路径组件,移除.并解析..
  3. 重新拼接处理后的组件与对应分隔符

代码实现

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:30:55