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

os.rename执行正则操作后报ValueError: embedded null byte错误求助

问题描述

运行Python脚本为文件添加后缀时,执行os.rename函数抛出ValueError: embedded null byte错误。脚本通过正则匹配文件扩展名,遍历目标目录为符合条件的文件名添加指定后缀,执行前打印的新旧路径显示正常,但路径中莫名混入空字节,尝试添加.encode("utf-8").strip()后仍未解决问题。

报错信息

Renaming chr1/tests/test-ch1.py to chr1/tests/test-ch1_ref.py...
Traceback (most recent call last):
  File "/Users/eomiso/Workspace/miso-projects/scripts/append_ref_to_filename.py", line 18, in <module>
    os.rename(old_path, new_path)
ValueError: embedded null byte

原代码

import os
import re

# Define the path to the directory containing the files
target_dir = "chr1/tests"
suffix = "_ref"

# Compile a regular expression to match file extensions
ext_pattern = re.compile(r"\.[^.]+$")

for root, dirs, files in os.walk(target_dir):
    for filename in files:
        if ext_pattern.search(filename) and not filename.endswith(suffix):
            old_path = os.path.join(root, filename)
            ext = ext_pattern.search(old_path).group()
            new_path = os.path.join(root, ext_pattern.sub(f"{suffix}\\0", filename)) + ext
            print(f"Renaming {old_path} to {new_path}...")
            os.rename(old_path.strip(), new_path.strip())

问题原因与修复

核心问题

代码中ext_pattern.sub(f"{suffix}\\0", filename)是错误根源:在f-string中,\\0会被解析为空字节(\x00),而非正则表达式中引用整个匹配结果的语法。这导致生成的new_path包含空字节,触发os.rename的参数合法性校验错误。

修复方案

将正则替换中的\\0改为\\g<0>(规范的正则组引用方式),同时简化冗余的扩展名处理逻辑:

修改后的代码:

import os
import re

target_dir = "chr1/tests"
suffix = "_ref"

ext_pattern = re.compile(r"\.[^.]+$")

for root, dirs, files in os.walk(target_dir):
    for filename in files:
        match = ext_pattern.search(filename)
        if match and not filename.endswith(suffix):
            old_path = os.path.join(root, filename)
            # 使用\\g<0>引用整个匹配的扩展名,避免生成空字节
            new_filename = ext_pattern.sub(f"{suffix}\\g<0>", filename)
            new_path = os.path.join(root, new_filename)
            print(f"Renaming {old_path} to {new_path}...")
            os.rename(old_path, new_path)

额外优化点

  • 直接在filename上完成替换生成新文件名,再拼接路径,避免重复处理路径字符串
  • 提前获取正则匹配对象,避免重复调用ext_pattern.search,提升代码效率
  • 移除不必要的.strip()调用,防止误删文件名中合法的首尾空格(若存在)

内容的提问来源于stack exchange,提问作者Aesop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:25:40