17

I have a regexp to validate file names. Here is it:

/[0-9a-zA-Z\^\&\'\@\{\}\[\]\,\$\=\!\-\#\(\)\.\%\+\~\_ ]+$/

It should allow file names like this:

aaa
aaa.ext
a#
A9#.ext

The following characters are not allowed \ / : * ? \" < > |

The problem is that file names like *.txt or /\kk passes the validation. I am doing validation with keyup event. So when I put one extra character after not allowed one it shows that everything is correct.

Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177
Rafael Sedrakyan
  • 2,541
  • 10
  • 34
  • 42
  • the accepted answer fixed your regex, but your regex is not correct for checking Windows filenames. [see here](https://learn.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file) – Leon Aug 09 '18 at 10:15

7 Answers7

42

For Windows names.

var isValid=(function(){
  var rg1=/^[^\\/:\*\?"<>\|]+$/; // forbidden characters \ / : * ? " < > |
  var rg2=/^\./; // cannot start with dot (.)
  var rg3=/^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; // forbidden file names
  return function isValid(fname){
    return rg1.test(fname)&&!rg2.test(fname)&&!rg3.test(fname);
  }
})();

isValid('file name');
Andrew D.
  • 8,130
  • 3
  • 21
  • 23
  • 2
    Escape / with \ in rg1. At least, VS 2010 thinks so. – noober Feb 09 '14 at 15:03
  • 1
    ^(?!\.)(?!com[0-9]$)(?!con$)(?!lpt[0-9]$)(?!nul$)(?!prn$)[^\|\*\?\\:<>/$"]*[^\.\|\*\?\\:<>/$"]+$ – Ryan Williams Dec 08 '14 at 03:44
  • Thanks @RyanWilliams for comment. But I know way to create file in Windows with long file name that contains dot in the end of file name and without extention :) – Andrew D. Dec 08 '14 at 05:19
  • Hi @Andrew D. If you want to permit filenames ending in a dot, try this one instead ^(?!\.)(?!com[0-9]$)(?!con$)(?!lpt[0-9]$)(?!nul$)(?!prn$)[^\|*\?\\:<>/$"]+$ if you wish to allow filenames starting with a . then simply remove the (?!\.) part. – Ryan Williams Dec 10 '14 at 23:09
  • 1
    It should be return !rg1.test(fname) && !rg2.test(fname) && !rg3.test(fname); I guess. – Sahil Chhabra Apr 28 '17 at 08:59
  • @mav3n You are wrong. _rg1.test(...)_ does not require _logical not_ operator. Check _isValid("foo.txt")_ and _isValid("fo:o.txt")_ – Andrew D. May 10 '17 at 12:50
  • 2
    AUX is missing, COM0 is actually valid, starting with "." is actually valid... [ref](https://learn.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file) – Leon Aug 09 '18 at 10:11
9

You need to add a starting anchor:

/^[0-9a-zA-Z ... ]+$/

This tells the engine to match from the start of the input all the way to the end of the input, whereas for your original expression it only needs to match at the end of the input.

Mattias Buelens
  • 19,609
  • 4
  • 45
  • 51
8

You need to anchor the expression by using ^ and $. For example:

/^[-\w^&'@{}[\],$=!#().%+~ ]+$/

Note that you need to escape - in a character class, or place it first/last.

Qtax
  • 33,241
  • 9
  • 83
  • 121
5
/^(?!\.)(?!com[0-9]$)(?!con$)(?!lpt[0-9]$)(?!nul$)(?!prn$)[^\|\*\?\\:<>/$"]*[^\.\|\*\?\\:<>/$"]+$/

Must not be empty.
Must not start with .
Must not be com0-com9, con, lpt0-lpt9, nul, prn
Must not contain | * ? \ : < > $
Must not end with .
Ryan Williams
  • 1,465
  • 15
  • 19
  • 1
    / (forward slash) is missing, AUX is missing, COM0 is actually valid, starting with "." is actually valid.... [ref](https://learn.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file) – Leon Aug 09 '18 at 10:10
3

Since this post (regex-for-windows-file-name) redirects to this question, I assume its about windows file names.

And based on the comment and reference by @Leon on the answer by @AndrewD, I made this regular expression and it works for me.

/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$|([<>:"\/\\|?*])|(\.|\s)$/ig

According to the naming-conventions (see reference above), I agree that "com0" should be a valid file name, but its not working if you try to name a file "com0" on windows, so I guess thats missing in the article.

So this regular expression would be more safe

/^(con|prn|aux|nul|com[0-9]|lpt[0-9])$|([<>:"\/\\|?*])|(\.|\s)$/ig
lale liley
  • 333
  • 3
  • 8
0

I would try something with this Regex (you can even make a validation attribute for ASP.NET MVC with it!):

@"^[^\u0022\u003C\u003E\u007C\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u003A\u002A\u003F\u005C\u002F]*$"

If it matches the input, it is valid filename (at least on Windows).

user2173353
  • 4,316
  • 4
  • 47
  • 79
0

try this:

^[0-9a-z_\-]{3,255}\.([a-z0-9]{2,5})$

its for any filename with minimum 3 chars and max length from 255 and an extension from 2 till 5 chars... the chars of the filename itself allowed for numbers, chars and minus sign and underscore ... maybe its helpful.

Ensai Tankado
  • 189
  • 1
  • 4