Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Invalid characters for Windows filenames
Information from :
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:
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.
Copy link

sagi053 commented Mar 24, 2020

Nice regex to find and replace invalid chars in file name.
"my file is * invalid ?.pdf".replace(/[<>:"/\|?*]/g,"");
$fileName = preg_replace('/[<>:"/\|?*]/','
','my file is * invalid ?.pdf');
var fileName = (new Regex(@"[<>:""/\|?*]")).Replace("my file is * invalid ?.pdf","_");

Copy link

doctaphred commented Mar 25, 2020

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.)

Copy link

Legorooj commented Apr 6, 2020

Copy link

doctaphred commented Apr 6, 2020

Thanks! I updated the URL 👍

Copy link

vollmann-ariel commented Apr 28, 2020

Thanks, dude!

Copy link

defrindr commented Jun 22, 2020

its very nice ,sir

Copy link

AnastasiaDunbar commented Jun 30, 2020


let toFilename=string=>string.replace(/\n/g," ").replace(/[<>:"/\\|?*\x00-\x1F]| +$/g,"").replace(/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/,x=>x+"_");

Copy link

ivan commented Nov 21, 2020

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.

Copy link

pitizzzle commented Jan 6, 2021

function filenameValidator(fname, { replacement = "�" } = {}) {

    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 {
        isOriginal: (fname === fname_original),

Copy link

pcrama commented Jan 15, 2021

For .Net, there is 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.

Copy link

syedsouban commented Nov 11, 2021

For Python3:
import re

Copy link

charlie39 commented Jun 6, 2022

Can a filename have space under windows?

Copy link

syedsouban commented Jun 6, 2022

Yes it can, you can verify by creating one yourself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment