【问题标题】:Regular expression for valid folder name c++ (windows)有效文件夹名称的正则表达式 c++ (windows)
【发布时间】:2012-10-18 19:38:37
【问题描述】:

我正在尝试使用正则表达式验证给定的文件夹名称,我尝试了一些测试并且效果很好,如果我完全安全或我的 reg 表达式遗漏了什么,请告诉我:

 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(我不想使用GetInvalidFileNameChars() 或任何其他api)

提前谢谢你。

【问题讨论】:

  • 您忘记了大小写混合的名称;在 UNC 路径中,所有这些名称实际上并没有被禁止。但总的来说,IMO 这些检查是一个无用的复杂性 - 只需尝试创建/打开/...目录并准备好处理故障(因为您已经应该这样做,因为 IO 总是会失败)。
  • @Andrey Windows,正在测试给定的文件夹基本名称以便稍后创建它,那么有没有比尝试打开它并处理失败更安全的解决方案?

标签: c++ regex qt directory


【解决方案1】:

对于某些系统来说肯定是错误的,因为什么是有效的目录名 将取决于系统,甚至可能取决于实际的文件系统: 远程安装的文件系统通常必须遵守 文件系统主机的约定,而不是本地系统的约定。

面对这种情况,有两种解决方案,根据实际情况而定 你想解决的问题。最简单的就是尝试创建 文件,并检查返回的错误。这会给你一个快速而 轻松检查名称在当前环境中是否合法。如果你 需要创建一个以后可以在任何地方读取的层次结构,但是, 最好的解决方案是采取非常保守的方法,只允许 字母数字字符和'_',甚至可能只有小写字母 和数字(以避免意外创建两个目录的风险 其名称仅在大小写上有所不同)。您可能还想限制 长度。 (历史上,有些系统只允许六个 字符,但今天听起来有点过分。)

关于禁用名称:这也非常依赖于系统, 并且可能取决于创建目录的位置。 (那里 在 Unix 下没有保留名称,但你几乎肯定会 如果您尝试在特定的环境中使用某些名称,则会遇到麻烦 目录:"local" 通常很好,但我不会尝试创建 它在"/usr/"下。)

【讨论】:

    【解决方案2】:

    在 Windows 环境中:

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

    带有 CASE_INSENSITIVE 和 UNICODE_CASE 修饰符。


    ^                                # 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.          
    

    【讨论】:

    • 如果您在纯 Windows 环境中,那么唯一合理的解决方案是为此使用 Windows 特定环境。 (当然,如果您只担心 Windows 和 Unix,那么 Unix 将接受 Windows 作为目录名称的几乎所有内容。)
    • 是的,我是在纯windows环境中,所以尝试创建文件夹并处理返回的错误会更容易吗?
    • @oumaya - 您可以使用上述正则表达式作为预验证,但当然您还需要处理错误。
    • 谢谢@Ωmega,我将使用正则表达式作为预验证,稍后检查是否成功创建具有给定名称的文件夹。
    • @oumaya - 作为预验证的一部分,您还应该检查目录是否不存在......祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 2011-11-21
    • 2016-11-16
    相关资源
    最近更新 更多