Skip to content

Instantly share code, notes, and snippets.

@doctaphred
Last active June 25, 2025 20:18
Show Gist options
  • Save doctaphred/d01d05291546186941e1b7ddc02034d3 to your computer and use it in GitHub Desktop.
Save doctaphred/d01d05291546186941e1b7ddc02034d3 to your computer and use it in GitHub Desktop.
Invalid characters for Windows filenames
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.
@sagi053
Copy link

sagi053 commented Mar 24, 2020

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

@doctaphred
Copy link
Author

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

@Legorooj
Copy link

Legorooj commented Apr 6, 2020

@doctaphred
Copy link
Author

Thanks! I updated the URL 👍

@vollmann-ariel
Copy link

Thanks, dude!

@defrindr
Copy link

its very nice ,sir

@AnastasiaDunbar
Copy link

AnastasiaDunbar commented Jun 30, 2020

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+"_");

@ivan
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.

@petrhdk
Copy link

petrhdk commented Jan 6, 2021

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),
    };
}

@pcrama
Copy link

pcrama commented Jan 15, 2021

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.

@professorlevi
Copy link

For Python3:
import re
re.sub(r'[<>:/\|?*"]+',"",filename)

@charlie39
Copy link

Can a filename have space under windows?

@professorlevi
Copy link

Yes it can, you can verify by creating one yourself

@haiueom
Copy link

haiueom commented Oct 22, 2022

Python3 :

def cleanFilename(sourcestring,  removestring ="\"|%:/,.\\[]<>*?") :
    return ''.join([c for c in sourcestring if c not in removestring])

@DNA-PC
Copy link

DNA-PC commented Oct 12, 2023

If you know of a good GitHub Action that detect (or replace) those filenames automatically, I'm looking for one.

@ychaouche
Copy link

ychaouche commented Feb 8, 2024

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?

@dmurvihill
Copy link

I'm struggling with "Any other character that the target file system does not allow." Is there a table of reserved characters for NTFS and the various FAT systems?

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