0

I am trying to valid a given folder name using a regular expression, I tried some tests and it works fine, please let me know if I am totally safe or my reg expression miss something:

 QRegExp regExp("^( [a-zA-Z] )( ( [a-zA-Z_\-\s0-9\.\)\(] )( [^\\!@#$%^&/:*?<>""|]* ) )*$" );
        QStringList ForbidenNameU;
        ForbidenNameU<<"CON"<<"PRN"<<"AUX"<<"NUL"<<"COM"<<"COM1"<<"COM2"<<"COM3"<<"COM4"<<"COM5"<<"COM6"<<"COM7"<<"COM8"<<"COM9"<<"LPT"<<"LPT1"<<"LPT2"<<"LPT3"<<"LPT4"<<"LPT5"<<"LPT6"<<"LPT7"<<"LPT8"<<"LPT9";
        QStringList ForbidenName;
        ForbidenName<<"con"<<"prn"<<"aux"<<"nul"<<"com"<<"com1"<<"com2"<<"com3"<<"com4"<<"com5"<<"com6"<<"com7"<<"com8"<<"com9"<<"lpt"<<"lpt1"<<"lpt2"<<"lpt3"<<"lpt4"<<"lpt5"<<"lpt6"<<"lpt7"<<"lpt8"<<"lpt9";

        if((Dirname->text().contains(regExp))&& !ForbidenNameU.contains(Dirname->text())&& !ForbidenName.contains(Dirname->text()))
        {
            validname=true;
            qDebug()<<"match in dir name = "<<regExp.cap(0);
            emit completeChanged();
        }...

PS(I don't want to use GetInvalidFileNameChars() or any other api )

Thank you in advance.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
Oumaya
  • 655
  • 4
  • 18
  • 43
  • 3
    You are forgetting mixed-case names; and in UNC paths, all those names aren't actually forbidden. But in general, IMO these checks are a useless complication - just try to create/open/... the directory and be ready to deal with the failure (as you already should, since IO can always fail). – Matteo Italia Oct 29 '12 at 13:26
  • possible duplicate of [How check if given string is legal (allowed) file name under Windows?](http://stackoverflow.com/questions/62771/how-check-if-given-string-is-legal-allowed-file-name-under-windows) – Andriy Oct 29 '12 at 13:27
  • @Andrey Windows, am testing the given folder basename to create it later, so is there a safer solution than trying to open it and handling failure? – Oumaya Oct 29 '12 at 13:48

2 Answers2

4

In Windows environmnent:

^(?!(?:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.[^.]*)?$)[^<>:"/\\|?*\x00-\x1F]*[^<>:"/\\|?*\x00-\x1F\ .]$

with CASE_INSENSITIVE and UNICODE_CASE modifiers.


^                                # Anchor to start of string.        
(?!                              # Assert filename is not: CON, PRN, 
  (?:                            # AUX, NUL, COM1, COM2, COM3, COM4, 
    CON|PRN|AUX|NUL|             # COM5, COM6, COM7, COM8, COM9,     
    COM[1-9]|LPT[1-9]            # LPT1, LPT2, LPT3, LPT4, LPT5,     
  )                              # LPT6, LPT7, LPT8, and LPT9...     
  (?:\.[^.]*)?                   # followed by optional extension    
  $                              # and end of string.                 
)                                # End negative lookahead assertion. 
[^<>:"/\\|?*\x00-\x1F]*          # Zero or more valid filename chars.
[^<>:"/\\|?*\x00-\x1F\ .]        # Last char is not a space or dot.  
$                                # Anchor to end of string.          
Ωmega
  • 42,614
  • 34
  • 134
  • 203
  • If you're in a Windows only environment, then the only reasonable solution would be to use the Windows specific environment for this. (Of course, if all you're worried about is Windows and Unix, Unix will accept just about everything Windows would as a directory name.) – James Kanze Oct 29 '12 at 13:58
  • yes am in a windows only environment, so it will be easier to try creating the folder and deal with the returned error? – Oumaya Oct 29 '12 at 14:04
  • @oumaya - You can use the above regex as a pre-validation, but certainly you need also handle errors. – Ωmega Oct 29 '12 at 14:14
  • thank you @Ωmega, I will use the regex as a pre-validation and check later if creating folder with the given name succeed. – Oumaya Oct 29 '12 at 14:25
  • @oumaya - As a part of pre-validation you should also check if the directory does not already exist... Good luck! – Ωmega Oct 29 '12 at 14:29
0

It's certainly wrong for some systems, as what is a valid directory name will depend on the system, and possibly even the actual file sy stem: remotely mounted file systems will typically have to obey the conventions for the file system host, and not for the local system.

Faced with this, there are two solutions, depending on the actual problem you want to solve. The simplest one is just to try to create the file, and check the error returned. This will give you a quick and easy check whether the name is legal in the current environment. If you need to create a hierarchy which can later be read anywhere, however, the best solution is to take a very conservative approach, only allowing alphanumeric characters and an '_', or possibly even only lower case and digits (to avoid any risk of accidentally creating two directories whose names differ only in case). You might also want to limit the length. (Historically, there have been systems which only allowed six characters, but that sounds a bit excessive today.)

With regards to the forbidden names: this is also very system dependent, and likely to depend on where the directories are being created. (There are no reserved names under Unix, but you're almost certainly going to run into trouble if you try to use certain names in specific directories: "local" is fine in general, but I wouldn't try to create it under "/usr/".)

James Kanze
  • 150,581
  • 18
  • 184
  • 329