当前位置:  开发笔记 > 编程语言 > 正文

用于文件名的字符串清理程序

如何解决《用于文件名的字符串清理程序》经验,为你挑选了10个好方法。

我正在寻找一个PHP函数,它将清理一个字符串,并准备用于文件名.谁知道一个方便的?

(我可以写一个,但我担心我会忽略一个角色!)

编辑:用于保存Windows NTFS文件系统上的文件.



1> Sean Vieira..:

对Tor Valamo的解决方案进行小幅调整以解决Dominic Rodger注意到的问题,您可以使用:

// Remove anything which isn't a word, whitespace, number
// or any of the following caracters -_~,;[]().
// If you don't need to handle multi-byte characters
// you can use preg_replace rather than mb_ereg_replace
// Thanks @?ukasz Rysiak!
$file = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $file);
// Remove any runs of periods (thanks falstro!)
$file = mb_ereg_replace("([\.]{2,})", '', $file);


我喜欢正则表达的瘾君子!-_〜
请注意:是非法的.
@ iim.hlk - 是的,它错过了包裹括号.我现在已经添加了这些.谢谢!
那里有一个缺陷,你应该把它分成两个,然后再检查`..`.例如`.?.`最终会成为`..`.虽然你过滤了`/`我现在无法看到你如何进一步利用它,但它显示了为什么检查`..`在这里是无效的.更好但可能,不要替换,只要拒绝,如果它没有资格.
因为这些值都不是[在Windows文件系统上是非法的](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx),为什么要丢失更多的信息呢?你可以将正则表达式简单地改为`[^ a-z0-9 _-]`如果你想要真正限制 - 或者只是使用生成的名称并丢弃给定的名称并避免*all*这些问题.:-)

2> SequenceDigi..:

那么使用rawurlencode()呢? http://www.php.net/manual/en/function.rawurlencode.php

这个功能甚至可以消毒中国的Chars:

public static function normalizeString ($str = '')
{
    $str = strip_tags($str); 
    $str = preg_replace('/[\r\n\t ]+/', ' ', $str);
    $str = preg_replace('/[\"\*\/\:\<\>\?\'\|]+/', ' ', $str);
    $str = strtolower($str);
    $str = html_entity_decode( $str, ENT_QUOTES, "utf-8" );
    $str = htmlentities($str, ENT_QUOTES, "utf-8");
    $str = preg_replace("/(&)([a-z])([a-z]+;)/i", '$2', $str);
    $str = str_replace(' ', '-', $str);
    $str = rawurlencode($str);
    $str = str_replace('%', '-', $str);
    return $str;
}

这是解释

    剥离HTML标签

    删除中断/标签/返回托架

    删除文件夹和文件名的非法字符

    将字符串放在小写字母中

    删除Éàû等外来口音,将其转换为html实体,然后删除代码并保留字母.

    用短划线替换空格

    编码可以通过前面步骤并在服务器上输入冲突文件名的特殊字符.恩."中文百强网"

    用短划线替换"%"以确保在查询文件时浏览器不会重写文件的链接.

好的,一些文件名不会重新发布,但在大多数情况下它会起作用.

恩.原名:"საბეჭდი-და-ტიპოგრაფიული.jpg"

输出名称:" - E1-83-A1-E1-83-90-E1-83-91-E1-83-94-E1-83-AD-E1-83-93-E1-83-98 - E1- 83-93-E1-83-90 - E1-83-A2-E1-83-98-E1-83-9E-E1-83-9D-E1-83-92-E1-83-A0-E1-83 -90-E1-83-A4-E1-83-98-E1-83-A3-E1-83-9A-E1-83-98.jpg"

它比404错误更好.

希望这很有帮助.

卡尔.



3> Dominic Rodg..:

而不是担心忽视角色 - 如何使用角色白名单,你很乐意被使用?例如,你可以让刚刚好醇" a-z,0-9,_,和一段时间的单个实例(.).这显然比大多数文件系统更具限制性,但应该保证您的安全.


对于使用变音符号的语言没有用处.这将导致魁北克的Qubec,杜塞尔多夫的杜塞尔多夫等等.
是的 - 但就像我说的那样:"例如".
这可能是OP完全可以接受的.否则,请使用http://php.net/manual/en/class.normalizer.php之类的内容
这实际上不是所要求的.op要求一个函数来清理字符串,而不是替代.
@ i.am.michiel,或许,但鉴于OP接受了它,我会认为他们发现它有用.

4> Philipp..:

解决方案1 - 简单有效

$file_name = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $url ) );

strtolower()保证文件名是小写的(因为在URL内部无关紧要,但在NTFS文件名中)

[^a-z0-9]+ 将确保,文件名只保留字母和数字

替换无效字符可'-'保持文件名可读

例:

URL:  http://stackoverflow.com/questions/2021624/string-sanitizer-for-filename
File: http-stackoverflow-com-questions-2021624-string-sanitizer-for-filename

解决方案2 - 用于很长的URL

您想要缓存URL内容,只需要具有唯一的文件名.我会用这个函数:

$file_name = md5( strtolower( $url ) )

这将创建一个固定长度的文件名.在大多数情况下,MD5哈希足以满足此类用途.

例:

URL:  https://www.amazon.com/Interstellar-Matthew-McConaughey/dp/B00TU9UFTS/ref=s9_nwrsa_gw_g318_i10_r?_encoding=UTF8&fpl=fresh&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=desktop-1&pf_rd_r=BS5M1H560SMAR2JDKYX3&pf_rd_r=BS5M1H560SMAR2JDKYX3&pf_rd_t=36701&pf_rd_p=6822bacc-d4f0-466d-83a8-2c5e1d703f8e&pf_rd_p=6822bacc-d4f0-466d-83a8-2c5e1d703f8e&pf_rd_i=desktop
File: 51301f3edb513f6543779c3a5433b01c


也许MD5可能出现问题:使用带有URL的哈希时要小心.虽然URL的数字http://www.skrenta.com/2007/08/md5_tutorial.html的平方根仍然比当前的网页大小要大得多,如果你碰到碰撞,你会得到关于布兰妮的网页当你期待有关Bugzilla的网页时,Spears.在我们的案例中它可能不是问题,但对于数十亿页我会选择更大的哈希算法,如SHA 256或完全避免它.资料来源:https://boyter.org/2013/01/code-for-a-search-engine-in-php-part-1/

5> mgutt..:

这就是您可以根据要求清理文件系统的方法

function filter_filename($name) {
    // remove illegal file system characters https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
    $name = str_replace(array_merge(
        array_map('chr', range(0, 31)),
        array('<', '>', ':', '"', '/', '\\', '|', '?', '*')
    ), '', $name);
    // maximise filename length to 255 bytes http://serverfault.com/a/9548/44086
    $ext = pathinfo($name, PATHINFO_EXTENSION);
    $name= mb_strcut(pathinfo($name, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($name)) . ($ext ? '.' . $ext : '');
    return $name;
}

在文件系统中允许其他所有内容,因此问题得到了完美的回答......

...但是如果稍后在不安全的HTML上下文中使用它,那么在文件名中允许使用单引号可能会很危险,'因为这个绝对合法的文件名:

 ' onerror= 'alert(document.cookie).jpg

成为一个XSS漏洞:


// output:

正因为如此,流行的CMS软件WordPress的中删除,他们学会了一年的年通过艰辛的道路(很多错误报告),这是添加越来越多的人物有用:

$special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0));
// ... a few rows later are whitespaces removed as well ...
preg_replace( '/[\r\n\t -]+/', '-', $filename )

最后,他们的列表现在包括URI rerserved-characters和URL unsafe characters list的大部分字符.

当然你可以简单地在HTML输出上编码所有这些字符,但是大多数开发人员和我也遵循成语"更安全而不是抱歉"并提前删除它们.

所以最后我建议使用这个:

function filter_filename($filename, $beautify=true) {
    // sanitize filename
    $filename = preg_replace(
        '~
        [<>:"/\\|?*]|            # file system reserved https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
        [\x00-\x1F]|             # control characters http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
        [\x7F\xA0\xAD]|          # non-printing characters DEL, NO-BREAK SPACE, SOFT HYPHEN
        [#\[\]@!$&\'()+,;=]|     # URI reserved https://tools.ietf.org/html/rfc3986#section-2.2
        [{}^\~`]                 # URL unsafe characters https://www.ietf.org/rfc/rfc1738.txt
        ~x',
        '-', $filename);
    // avoids ".", ".." or ".hiddenFiles"
    $filename = ltrim($filename, '.-');
    // optional beautification
    if ($beautify) $filename = beautify_filename($filename);
    // maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
    $ext = pathinfo($filename, PATHINFO_EXTENSION);
    $filename = mb_strcut(pathinfo($filename, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($filename)) . ($ext ? '.' . $ext : '');
    return $filename;
}

其他不会导致文件系统出现问题的其他内容应该是附加功能的一部分:

function beautify_filename($filename) {
    // reduce consecutive characters
    $filename = preg_replace(array(
        // "file   name.zip" becomes "file-name.zip"
        '/ +/',
        // "file___name.zip" becomes "file-name.zip"
        '/_+/',
        // "file---name.zip" becomes "file-name.zip"
        '/-+/'
    ), '-', $filename);
    $filename = preg_replace(array(
        // "file--.--.-.--name.zip" becomes "file.name.zip"
        '/-*\.-*/',
        // "file...name..zip" becomes "file.name.zip"
        '/\.{2,}/'
    ), '.', $filename);
    // lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625
    $filename = mb_strtolower($filename, mb_detect_encoding($filename));
    // ".file-name.-" becomes "file-name"
    $filename = trim($filename, '.-');
    return $filename;
}

此时,如果结果为空,则需要生成文件名,并且可以决定是否要编码UTF-8字符.但是您不需要这样,因为在Web托管上下文中使用的所有文件系统中都允许使用UTF-8.

您唯一要做的就是使用urlencode()(因为您希望使用所有URL),因此文件名将???????_???????.jpg成为您的URL :http: //www.maxrev.de/html/img/%E1%83% A1%E1%83%90%E1%83%91%E1%83%94%E1%83%AD%E1%83%93%E1%83%98_%E1%83%9B%E1%83%90% E1%83%9C%E1%83%A5%E1%83%90%E1%83%9C%E1%83%90.jpg

Stackoverflow就是这样做的,所以我可以像用户那样发布这个链接:http:
//www.maxrev.de/html/img/საბეჭდი_მანქანა.jpg

所以这是一个完整的法律文件名和不是一个问题,因为@ SequenceDigitale.com在他的回答中提到.


做得好。对我来说最有帮助的答案。+1

6> Tor Valamo..:
preg_replace("[^\w\s\d\.\-_~,;:\[\]\(\]]", '', $file)

根据系统允许的内容添加/删除更多有效字符.

或者,您可以尝试创建该文件,然后如果错误则返回错误.


这将允许通过像`..`这样的文件名,这可能是也可能不是问题.

7> 小智..:

那么,tempnam()会为你做的.

http://us2.php.net/manual/en/function.tempnam.php

但这创造了一个全新的名称.

要清理现有字符串,只需限制用户可以输入的内容并将其设置为字母,数字,句点,连字符和下划线,然后使用简单的正则表达式进行清理.检查哪些字符需要转义,否则可能会出现误报.

$sanitized = preg_replace('/[^a-zA-Z0-9\-\._]/','', $filename);



8> 120DEV..:

PHP提供了一种将文本清理为不同格式的功能

filter.filters.sanitize

如何 :

echo filter_var(
   "Lorem Ipsum has been the industry's",FILTER_SANITIZE_URL
); 

大段引用 LoremIpsumhasbeentheindustry's



9> Sampson..:

以下表达式创建一个漂亮,干净且可用的字符串:

/[^a-z0-9\._-]+/gi

转向今天的财务:计费今天的财务计费


@Jonathan - 斜体是什么?

10> CarlJohnson..:

对Sean Vieira的解决方案进行小幅调整以允许单点,您可以使用:

preg_replace("([^\w\s\d\.\-_~,;:\[\]\(\)]|[\.]{2,})", '', $file)

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有