用正则表达式替换文件名中的字符 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 层的文件系统操作。
它会立即对您的系统产生影响,并且无法轻易撤消。
所以也算是很关键了。
想象一下,您的重命名没有按预期进行。然后所有文件都可以重命名为神秘的混乱,最坏的情况是(像勒索软件一样有害)。
我的脚本应该替换“|”它通过正则表达式在带有“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 看看结果是否如您所愿。
已修复和改进
这是我的复制粘贴代码,带有一些突出显示的内联注释:
#!/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 层的文件系统操作。
它会立即对您的系统产生影响,并且无法轻易撤消。
所以也算是很关键了。 想象一下,您的重命名没有按预期进行。然后所有文件都可以重命名为神秘的混乱,最坏的情况是(像勒索软件一样有害)。