用正则表达式替换文件名中的字符 python

Replace character in file name with regex python

我的脚本应该替换“|”它通过正则表达式在带有“l”的目录中找到的文件的字符。

代码运行但文件名没有被替换。怎么了?

#!/usr/bin/python

import os
from posixpath import dirname
import re
import glob
import fnmatch

class bcolors:
    HEADER = '3[95m'
    OKBLUE = '3[94m'
    OKCYAN = '3[96m'
    OKGREEN = '3[92m'
    WARNING = '3[93m'
    FAIL = '3[91m'
    ENDC = '3[0m'
    BOLD = '3[1m'
    UNDERLINE = '3[4m' 

#Path
file_src = dirname(os.path.abspath(__file__))

#Current directory name
print(bcolors.OKBLUE + bcolors.BOLD + 'Directory:', file_src)
'\n'

#List all files in directory
list_file = os.listdir(file_src)
print(bcolors.BOLD + 'In this directory:', '\n', list_file)
'\n'

#Finding all the "|" characters in a string
file_pattern = re.compile('[\":<>;|*?]*')


#Replace "|" with "l"
list = str(list_file)
re.sub(file_pattern, 'l', list, re.I)

您的示例存在一些问题:

list = str(list_file)

这一行是

  • shadowing a reserved keyword in Python(不要命名变量list),
  • 我不认为它在做你认为它在做的事情。它没有给你一个字符串列表。它为您提供 list_file
  • 的字符串表示
  • 您的 list_file 已经是一个字符串列表。我怀疑你写这个是为了让你的 re.sub 函数调用对单个事物进行操作,但你最好使用 list comprehension

下一行:

re.sub(file_pattern, 'l', list, re.I)

您需要为 list_ 中的每个 str 执行 .sub,并将结果分配给变量:

replaced_list_file = [re.sub(file_pattern, 'l', f, re.I) for f in list_file]

但正如多位评论者所说,编译模式是否真的按照您认为的那样进行?看看 this link 看看结果是否如您所愿。

and the many comments, especially the ,已指出问题并指导解决方案。

已修复和改进

这是我的复制粘贴代码,带有一些突出显示的内联注释:

#!/usr/bin/python

import os
from posixpath import dirname
import re
import glob
import fnmatch

class bcolors:
    HEADER = '3[95m'
    OKBLUE = '3[94m'
    OKCYAN = '3[96m'
    OKGREEN = '3[92m'
    WARNING = '3[93m'
    FAIL = '3[91m'
    ENDC = '3[0m'
    BOLD = '3[1m'
    UNDERLINE = '3[4m' 
    RESET = '\u001b[0m' # added to get regular style

def print_list(files):
    '''Print a list, one element per line.'''
    for f in files:
        print(bcolors.OKBLUE + f + bcolors.RESET)

#Path
directory = dirname(os.path.abspath(__file__))

#Current directory name
print(bcolors.BOLD + 'Directory:' + bcolors.OKBLUE, directory)
print(bcolors.RESET)

#List all files in directory
files = os.listdir(directory)
print(bcolors.BOLD + 'In this directory:' + bcolors.OKBLUE, len(files), bcolors.RESET + 'files')
print_list(files)

#Finding all the "|" characters in a string
pipe_pattern = re.compile('\|')  # need to escape the special character pipe (in regex means logical-OR)


#Replace "|" with "l"
renamed_files = []
for f in files:
    f_renamed = re.sub(r'\|', 'l', f, re.I)
    if (str(f_renamed) != str(f)):
        renamed_files.append(f_renamed)

# print the list of filenames, each on a separate line
print(bcolors.BOLD, "Renamed:" + bcolors.OKGREEN, len(renamed_files), bcolors.RESET + "files")
print_list(renamed_files)

说明

  • 匹配管道字符的简单正则表达式是 \|
  • 注意:需要前置反斜杠来转义特殊字符(如 |(或)、\ 转义、() 分组等)
  • 有时将代码块提取到函数中很有用(例如 def print_list)。这些可以很容易地测试。

测试你的替代品

要测试您的替换,一个简单的函数会有所帮助。 然后你可以用一个虚构的例子来测试它。

def replace_pipe(file):
    return file.replace('|', 'l') # here the first argument is no regex, thus not escaped!

### Test it with an example first
print( replace_pipe('my|file.txt') )

如果一切按预期进行。然后添加更多(关键)步骤。

避免将 I/O 层集成到早期

详细说明os.rename 是 I/O 层的文件系统操作。 它会立即对您的系统产生影响,并且无法轻易撤消。

所以也算是很关键了。 想象一下,您的重命名没有按预期进行。然后所有文件都可以重命名为神秘的混乱,最坏的情况是(像勒索软件一样有害)。