validationWindows文件名

如何确定给定的string是否是有效的Windows文件名? 我在想一些函数,我可以给一个string,并返回一个布尔值。 它应该检查不允许的字符(<>:“/ \ |?*)和保留字(CON,PRN等)。

isValidWindowsFilename('readme.txt'); // true isValidWindowsFilename('foo/bar'); // false isValidWindowsFilename('CON'); // false 

我已经find了一个MSDN参考,描述了什么是有效的: http : //msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx

我也发现了同样的Java问题,除了它是Java而不是PHP: 在Windows上validation文件名

Solutions Collecting From Web of "validationWindows文件名"

这是Java问题的答案,移植到PHP。

 /** * @param string $filename * @return boolean Whether the string is a valid Windows filename. */ function isValidWindowsFilename($filename) { $regex = <<<'EOREGEX' ~ # start of regular expression ^ # Anchor to start of string. (?! # Assert filename is not: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. (CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9]) (\.[^.]*)? # 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. # # tilde = end of regular expression. # i = pattern modifier PCRE_CASELESS. Make the match case insensitive. # x = pattern modifier PCRE_EXTENDED. Allows these comments inside the regex. # D = pattern modifier PCRE_DOLLAR_ENDONLY. A dollar should not match a newline if it is the final character. ~ixD EOREGEX; return preg_match($regex, $filename) === 1; } 

请注意,此功能不会对文件名的长度施加任何限制,但根据平台,实际文件名可能被限制为260或32767个字符。

这里有一些测试代码来验证它的正确性。

 $tests = array( // Valid filenames 'readme.txt' => true, 'foo.AUX' => true, 'foo.AUX.txt' => true, '.gitignore' => true, // starting with a period is ok. // Invalid filenames 'x<y' => false, // less than not allowed. 'x>y' => false, // greater than not allowed. 'q: why not.txt' => false, // colon not allowed. 'He said "hi".doc' => false, // double quote not allowed. 'foo/bar' => false, // Forward slash not allowed. 'foo\\bar' => false, // Backslash not allowed. 'cat readme | backup' => false, // vertical bar (pipe) not allowed. 'ls foo?.rtf' => false, // question mark not allowed 'ls foo*.rtf' => false, // asterisk not allowed "null\0char" => false, // null character not allowed '.' => false, // must not end in period '..' => false, // must not end in period 'period.' => false, // must not end in period 'space ' => false, // must not end with space // Do not use the following reserved device names for the name of a file: // CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. // Also avoid these names followed immediately by an extension; for example, NUL.txt is not recommended. 'CON' => false, 'prn.txt' => false, 'LPT9.php' => false, ); // Disallow characters whose integer representations are in the range from 1 through 31 for ($i = 1; $i <= 31; $i++) { $tests[chr($i)] = false; } ?> <style> .pass { background-color: #efe; } .fail { background-color: #fee; } </style> <table> <thead><tr><th>filename</th><th>expected</th><th>actual</th></tr></thead> <tbody> <? foreach ($tests as $filename => $expected) { $actual = isValidWindowsFilename($filename); ?> <tr><td><?=htmlentities($filename)?></td><td><?= $expected ? 'valid' : 'invalid' ?></td><td class="<?= $expected === $actual ? 'pass' : 'fail' ?>"><?= $actual ? 'valid' : 'invalid' ?></td></tr> <? } ?> </tbody> </table>