检查文件名是否有效
在Python中,怎样才能最稳妥地检查一个文件名在所有平台上(包括手机平台,比如Android和iOS)是否有效呢?
举个例子:
this_is_valid_name.jpg -> 有效
**adad.jpg -> 无效
a/ad -> 无效
3 个回答
-2
相关主题是:“文件名模式匹配”。
这里有一些你可以使用的方法和函数:
字符串方法 endswith() 和 startswith()
fnmatch.fnmatch()
glob.glob()
pathlib.Path.glob()
import os
# Get .txt files
for f_name in os.listdir('some_directory'):
if f_name.endswith('.txt'):
print(f_name)
使用 fnmatch() 进行简单的文件名模式匹配
import os
import fnmatch
for file_name in os.listdir('some_directory/'):
if fnmatch.fnmatch(file_name, '*.txt'):
print(file_name)
更高级的模式匹配
for filename in os.listdir('.'):
if fnmatch.fnmatch(filename, 'data_*_backup.txt'):
print(filename)
使用 glob 进行文件名模式匹配
import glob
glob.glob('*.py')
或者代码如下
import glob
for name in glob.glob('*[0-9]*.txt'):
print(name)
或者匹配如下
import glob
for file in glob.iglob('**/*.py', recursive=True):
print(file)
或者代码如下
from pathlib import Path
p = Path('.')
for name in p.glob('*.p*'):
print(name)
1
我自己写了一个函数。我是以@Voo的回答为基础,然后根据这个回答添加了一些检查。
import re
def is_valid_folder_name(name: str):
# Define a regular expression pattern to match forbidden characters
ILLEGAL_NTFS_CHARS = r'[<>:/\\|?*\"]|[\0-\31]'
# Define a list of forbidden names
FORBIDDEN_NAMES = ['CON', 'PRN', 'AUX', 'NUL',
'COM1', 'COM2', 'COM3', 'COM4', 'COM5',
'COM6', 'COM7', 'COM8', 'COM9',
'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5',
'LPT6', 'LPT7', 'LPT8', 'LPT9']
# Check for forbidden characters
match = re.search(ILLEGAL_NTFS_CHARS, name)
if match:
raise ValueError(
f"Invalid character '{match[0]}' for filename {name}")
# Check for forbidden names
if name.upper() in FORBIDDEN_NAMES:
raise ValueError(f"{name} is a reserved folder name in windows")
# Check for empty name (disallowed in Windows)
if name.strip() == "":
raise ValueError("Empty file name not allowed in Windows")
# Check for names starting or ending with dot or space
match = re.match(r'^[. ]|.*[. ]$', name)
if match:
raise ValueError(
f"Invalid start or end character ('{match[0]}')"
f" in folder name {name}"
)
在你的例子中:
$ is_valid_folder_name('this_is_valid_name.jpg')
$ is_valid_folder_name('**adad.jpg')
---------------------------------------------------------------------------
ValueError in is_valid_folder_name(name)
13 match = re.search(ILLEGAL_NTFS_CHARS, name)
14 if match:
---> 15 raise ValueError(
16 f"Invalid character {match[0]} for filename {name}")
17 # Check for forbidden names
ValueError: Invalid character '*' for filename **adad.jpg
$ is_valid_folder_name('a/ad')
---------------------------------------------------------------------------
ValueError in is_valid_folder_name(name)
13 match = re.search(ILLEGAL_NTFS_CHARS, name)
14 if match:
---> 15 raise ValueError(
16 f"Invalid character {match[0]} for filename {name}")
17 # Check for forbidden names
ValueError: Invalid character '/' for filename a/ad
如果有人发现我漏掉了什么,请随意补充或评论!
4
检查一个文件名在你目标操作系统上是否有效,最直接的方法就是把它和一份经过测试的文件名列表对比。
valid = myfilename in ['this_is_valid_name.jpg']
进一步说,你可以定义一套允许的字符,这些字符在所有平台上都是可以用作文件名的:
valid = set(valid_char_sequence).issuperset(myfilename)
不过,这样还不够,因为有些操作系统有保留的文件名。
你需要排除这些保留的名字,或者创建一个表达式(正则表达式),用来匹配操作系统允许的文件名范围,并且在每个目标平台上测试你的文件名。
据我所知,Python并没有提供这样的帮助工具,因为它遵循一个原则:宁可事后求原谅,也不要事先请求许可。因为不同的操作系统和文件系统组合很多,等操作系统抛出异常时再做出反应,往往比提前检查所有可能的安全文件名范围要简单。