PHP正则表达式匹配文件路径

9

有人能帮我解决这个preg_match问题吗?

if (preg_match('~[^A-Za-z0-9_\./\]~', $filepath))
    // Show Error message.

我需要匹配可能的文件路径。因此,我需要检查双斜杠等情况。有效的文件路径字符串应该只像这样:

mydir/aFile.php

或者

mydir/another_dir/anyfile.js

所以,这个字符串开头的斜杠也应该被检查。请帮忙。

谢谢 :)

编辑: 另外,各位,这个路径是从文本文件中读取的。它不是系统上的文件路径。因此,在这种情况下,希望它能支持所有系统。

重新编辑: 抱歉,但字符串也可能看起来像这样: myfile.php,或 myfile.js,或 myfile.anything

我如何允许这样的字符串?对于之前没有太具体说明,我感到抱歉...


只有你展示的这两个示例路径应该匹配? - codaddict
任何文件扩展名都应该匹配。字符串前面不能有任何斜杠,字符串末尾也不能有任何斜杠。这是唯一的限制,它必须是A-Z、a-z、0-9字符,或者具有下划线或点。就是这样。 - SoLoGHoST
路径应该对哪些文件系统有效? - Gumbo
尽可能翻译全部内容,否则翻译大部分。 - SoLoGHoST
@SoLoGHoST:有数十种不同的文件系统,每个都有不同的规格(请参见http://en.wikipedia.org/wiki/Comparison_of_file_systems)。这些规格的并集可能只是文件名的`[A-Z0-9]{1,8}`(MS-DOS仅允许8字节),路径长度总共30字节(Apple DOS 3.x仅允许30字节)。 - Gumbo
也许有一个不同的函数,比如PHP字符串函数中最适合的一个。这是来自文本文件内部的文本...所以不确定文件系统是否重要。 - SoLoGHoST
2个回答

15
请注意,有许多可能的文件路径类型。 例如:
- "./" - "../" - "........"(是的,这可以是文件名) - "file/file.txt" - "file/file" - "file.txt" - "file/.././/file/file/file" - "/file/.././/file/file/.file"(UNIX) - "C:\Windows\"(Windows) - "C:\Windows\asd/asd"(Windows,php 接受此格式) - "file/.././/file/file/file!@#$" - "file/.././/file/file/file!@#.php.php.php.pdf.php"
所有这些文件路径都是有效的。我想不出一个简单的正则表达式可以完美解决。
现在假设它只是 UNIX 路径,这是我认为应该适用于大多数情况的内容:
preg_match('/^[^*?"<>|:]*$/',$path)

它检查所有字符串中的 ^, *, ?, ", <, >, | 和 :(在 Windows 中需要删除)。这些字符都是Windows不允许用于文件名的字符,以及 / 和 .

如果是Windows系统,您应该将路径中的 \ 替换为 /,然后分割它并检查是否为绝对路径。以下是一个同时适用于Unix和Windows的示例。

function is_filepath($path)
{
    $path = trim($path);
    if(preg_match('/^[^*?"<>|:]*$/',$path)) return true; // good to go

    if(!defined('WINDOWS_SERVER'))
    {
        $tmp = dirname(__FILE__);
        if (strpos($tmp, '/', 0)!==false) define('WINDOWS_SERVER', false);
        else define('WINDOWS_SERVER', true);
    }
    /*first, we need to check if the system is windows*/
    if(WINDOWS_SERVER)
    {
        if(strpos($path, ":") == 1 && preg_match('/[a-zA-Z]/', $path[0])) // check if it's something like C:\
        {
            $tmp = substr($path,2);
            $bool = preg_match('/^[^*?"<>|:]*$/',$tmp);
            return ($bool == 1); // so that it will return only true and false
        }
        return false;
    }
    //else // else is not needed
         return false; // that t
}

我能否将所有可能的正则表达式连接成一个正则表达式? - Ronak Patel

9

您可以做以下事情:

if(preg_match('#^(\w+/){1,2}\w+\.\w+$#',$path)) {
        // valid path.
}else{
        // invalid path
}

我可以这样使用它来仅检查无效路径吗? if(!preg_match('#^(\w+/){1,2}\w+\.\w+$#',$path)) - SoLoGHoST
抱歉,这个不起作用,我尝试了一下,但当我有这个字符串时,它会出现错误消息:myfile.php - SoLoGHoST
好的,它不一定要有斜杠,我该如何修改以考虑到这一点呢? - SoLoGHoST
1
preg_match('#^(\w+/){0,2}\w+.\w+$#',$path) - MartyIX
1
请查看有关正则表达式的教程:http://www.webcheatsheet.com/php/regular_expressions.php - MartyIX
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接