【问题标题】:Regex: How to validate that a path does not contain //正则表达式:如何验证路径不包含 //
【发布时间】:2011-04-18 07:42:54
【问题描述】:

我需要帮助来创建一个正则表达式(用于 JavaScript .match 和 PHP preg_match),以验证文件的 unix 类型绝对路径(带有国际字符,例如 åäöøæð 等),以便:

  1. /path/to/someWhere 有效
  2. /path/tø/sömewhere 有效
  3. /path/to//某处无效
  4. 路径/到/某处无效
  5. /path/to/somewhere/ 无效

无论深度如何,正则表达式都需要处理路径(/path/to 或 /path/to/somewhere 或 /path/to/somewhere/else)

我有一个正则表达式将 1 到 3 标记为有效 /^\/.+[^\/]$/ ,问题是使这个正则表达式不将 3 标记为有效,因为它包含 // 没有任何其他字符介于两者之间。

【问题讨论】:

  • 我喜欢这样的正则表达式帖子,在外人看来我们都像是垃圾邮件机器人之类的。
  • Unix/Linux 路径名如果以斜杠结尾或有双斜杠,实际上可以正常工作。

标签: php javascript regex path


【解决方案1】:

这应该可行:

^/[^/]?$|^/[^/]([^/]|/[^/])*?[^/]$

它允许除/ 之外的任何字符, / 后跟/ 之外的任何字符。它还确保最后一个字符不是/,并且第二个字符也不是一个。

最后,这使用了/ 而没有转义。要在 PHP 中使用它,不要使用 / 作为正则表达式分隔符——这只会使正则表达式难以阅读。使用任何其他字符,例如; 改为分隔表达式:

;^/[^/]?$|^/[^/]([^/]|/[^/])*?[^/]$;

编辑:为根路径 "/" 和由单个字母目录组成的路径添加了特殊处理。

【讨论】:

  • 这不匹配“/”,一个单斜杠,它是根目录的路径名。此外,非贪心量词可能会导致性能问题。
  • @Pointy:greedy 量词可能会导致性能问题。但是关于根路径的好电话。
  • 这取决于正则表达式。使用贪心量词可以显着减少回溯。 See this excellent blog post.
  • @Pointy: 是的,但在这种情况下没有嵌套量词,因此不会发生灾难性的回溯,在这种情况下,它实际上为我们节省了一次回溯,因为最后一个字符不会被消耗然后吐出再次。
  • 我不是专家。其中一天我需要尝试 Regex Buddy :-)
【解决方案2】:

这里真的不需要正则表达式。据我所知,您需要确保三件事:

  1. 字符串以/ 开头
  2. 字符串不以/ 结尾,除非整个字符串 /
  3. 字符串不包含// 的任何实例

以上三个都可以用字符串函数来完成。

在 PHP 中:

if ($string != '/' && ($string[0] != '/' || $string[strlen($string)-1] == '/' || strpos($string, '//') > -1))
{
  // string is invalid
}

在 Javascript 中:

if (string != '/' && (string.charAt(0) != '/' || string.charAt(string.length - 1) == '/' || string.indexOf('//') > -1))
{
  // string is invalid
}

资源:

【讨论】:

  • 由单斜杠组成的路径名有效的路径名。
【解决方案3】:

如果路径匹配^[^\/]|\/\/|.\/$,则无效。否则有效。

【讨论】:

  • 由单斜杠组成的路径名是有效的路径名。
【解决方案4】:

我认为这样做可以:

^(:?\/$|(:?\/[^/]+)+$)

这表示接受任何字符串,只是一个 /,或由一个或多个重复 / 后跟一个或多个非 / 字符的序列形成的任何字符串。

这使用了所有贪婪的量词,所以它应该很快;此外,出于性能考虑,^ 锚点已被分解。

这是一个 Javascript 正则表达式。我不是 PHP 程序员,所以我不知道的主要事情是非捕获组语法是否适用于 PHP。另外,我不确定您将如何处理“引用”斜杠字符。

【讨论】:

    【解决方案5】:

    PHP 的解决方案:

        $lines =  array(
            "/path/to/someWhere",
            "/path/tø/sömewhere",
            "/path/to//somewhere",
            "path/to/somewhere",
            "/path/to/somewhere/",
        );
    
        foreach($lines as $line){
            var_dump(preg_match('#^(/[^/]+)+$#',$line)); // dumps int(1) int(1) int(0) int(0) int(0) 
        }
    

    【讨论】:

    • 该模式不匹配“/”,一个单斜杠,它是一个有效的路径名。
    • ^(/[^/]+)+$ 正是我想要的,当你看到它时,它是如此简单。我忘了说我不想只验证 / 因为这个根级别是一种目录。这个正则表达式非常适合我的需要。谢谢
    • np,重复规则,重复规则
    【解决方案6】:

    它不是正则表达式,但也同样有效。

    str_replace('//', '/', $file)
    

    【讨论】:

    • 这不会执行所需的 3 项检查中的任何一项,它只会在一个条件下替换。
    • 我只是建议将您的普通 RegEx 与 str_replace 一起使用,而不是对 RegEx 发疯并造成次优的令牌灾难。鉴于 OP 中的 RegEx,是的,它确实满足了要求。
    猜你喜欢
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2016-12-12
    相关资源
    最近更新 更多