-
-
Save doctaphred/d01d05291546186941e1b7ddc02034d3 to your computer and use it in GitHub Desktop.
Information from https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file : | |
Use any character in the current code page for a name, including Unicode | |
characters and characters in the extended character set (128–255), except | |
for the following: | |
- The following reserved characters: | |
< (less than) | |
> (greater than) | |
: (colon) | |
" (double quote) | |
/ (forward slash) | |
\ (backslash) | |
| (vertical bar or pipe) | |
? (question mark) | |
* (asterisk) | |
- Integer value zero, sometimes referred to as the ASCII NUL character. | |
- Characters whose integer representations are in the range from 1 through | |
31, except for alternate data streams where these characters are | |
allowed. For more information about file streams, see File Streams. | |
- Any other character that the target file system does not allow. | |
- Do not use the following reserved names for the name of a file: | |
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, | |
COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. | |
Also avoid these names followed immediately by an extension; for | |
example, NUL.txt is not recommended. | |
- Do not end a file or directory name with a space or a period. Although | |
the underlying file system may support such names, the Windows shell and | |
user interface does not. However, it is acceptable to specify a period | |
as the first character of a name. For example, ".temp". | |
--- | |
Handy list to copy/paste: | |
<>:"/\|?* | |
--- | |
Note: Other OSs and file systems may vary; but in general, the only forbidden characters | |
in filenames on Unix-like systems appear to be the forward slash (/) and the null byte. |
The URL is old. The new docs URL is now https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
Thanks! I updated the URL 👍
Thanks, dude!
its very nice ,sir
JavaScript:
let toFilename=string=>string.replace(/\n/g," ").replace(/[<>:"/\\|?*\x00-\x1F]| +$/g,"").replace(/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/,x=>x+"_");
Microsoft's documentation neglects to mention COM0
and LPT0
which explorer.exe has trouble with (even on Windows 10 20H2), possibly because of a bug.
function filenameValidator(fname, { replacement = "�" } = {}) {
// https://stackoverflow.com/a/31976060
// https://gist.github.com/doctaphred/d01d05291546186941e1b7ddc02034d3
const fname_original = fname;
// resolve multi-line, whitespace trimming
fname = fname.split(/[\r\n]/).map(s => s.trim()).filter(s => s.length).join(" ");
// forbidden characters
// (after multi-line, because new-line-chars are themselves forbidden characters)
fname = fname.replaceAll(/[<>:"\/\\\|?*\x00-\x1F]/g, replacement);
// advanced trim
fname = fname.replace(/\.$/, "");
// empty filename
if (!fname.length) {
fname = '_';
}
// forbidden filenames
if (fname.match(/^(CON|PRN|AUX|NUL|COM1|COM2|COM3|COM4|COM5|COM6|COM7|COM8|COM9|LPT1|LPT2|LPT3|LPT4|LPT5|LPT6|LPT7|LPT8|LPT9)(\..+)?$/)) {
fname = `_${fname}`;
}
return {
fname,
isOriginal: (fname === fname_original),
};
}
For .Net, there is https://docs.microsoft.com/en-us/dotnet/api/system.io.path.getinvalidpathchars?view=net-5.0: name?.IndexOfAny(Path.GetInvalidFileNameChars()) == -1
or name?.IndexOfAny(Path.GetInvalidPathChars()) == -1
depending if you want to validate a file name or a full path.
It will still not catch issues with file names like NUL or COM on FAT or NTFS.
For Python3:
import re
re.sub(r'[<>:/\|?*"]+',"",filename)
Can a filename have space under windows?
Yes it can, you can verify by creating one yourself
Python3 :
def cleanFilename(sourcestring, removestring ="\"|%:/,.\\[]<>*?") :
return ''.join([c for c in sourcestring if c not in removestring])
If you know of a good GitHub Action that detect (or replace) those filenames automatically, I'm looking for one.
I'd like to rename a filename with a "-" (hyphen) suffix but windows (7) refuses.
Do you guys think this is forbidden only at the end of filenames?
Thanks for the contribution! Couple of notes:
\
is the escape character in most regex engines, so you'll need to repeat it to make sure it gets included in the character class and doesn't just escape the|
after it:[<>:"/\\|?*]
/"my file is \\ invalid ?.pdf".replace(/[<>:"/\\|?*]/g, "_");
Also, I'm not super confident in my PHP knowledge, but I think you'll need to double-escape the backslash: once because PHP treats it as an escape character in the string literal (even when using single quotes), and a second time for the regex engine. So I think you'll need a total of four
\
characters:'/[<>:"/\\\\|?*]/'
(gross).(It looks like C# uses the
@
prefix to denote verbatim strings, which look like Python's raw strings, and should only need a single escape for the regex engine. JS does not (yet) seem to offer unescaped string literals, but RegExp literals don't apply the additional layer of escaping.)