【问题标题】:Extracting filename from content disposition via PHP通过 PHP 从内容配置中提取文件名
【发布时间】:2015-03-01 12:51:05
【问题描述】:

我需要一个正则表达式从以下字符串中提取文件名(包括文件扩展名):

attachment; filename*=UTF-8''test.rar

或者像这样

attachment; filename*=UTF-8''Epost%20-test.part01.rar

目标:

test.rar
Epost%20-test.part01.rar

我该怎么做?

注意:我使用 preg_match 进行提取

【问题讨论】:

  • 文件是否每次都有一个. 点而没有别的?
  • 每个文件都有一个类似上面的扩展名(例如 rar)。我不明白你在问什么。我需要解压test.rar
  • 那我希望我的回答能解决你的问题:D

标签: php preg-match content-disposition


【解决方案1】:

这应该适合你:

<?php

    $str = "attachment; filename*=UTF-8''test.rar";

    preg_match_all("/\w+\.\w+/", $str, $output);

    echo $output[0][0];

?>

输出:

test.rar

编辑:

如果 2 个单引号每次都在字符串中,您可以使用以下命令抓取所有内容:

<?php

    $str = "attachment; filename*=UTF-8''Epost%20-test.part01.rar";

    preg_match_all("/[^\'\']+$/", $str, $output);

    echo $output[0][0];

?>

输出:

Epost%20-test.part01.rar 

【讨论】:

  • 为什么要投反对票?它有效,正是 op 想要的?!
  • 啊……现在,我知道你在问什么了。对造成的不便表示歉意。文件名也可以是这样的:附件;文件名*=UTF-8''Epost%20-test.part01.rar
  • @user2826075 是否有两个单引号?
  • 哇,就是这样。非常感谢:)
  • 如果文件名中有空格,这不起作用。
【解决方案2】:

不确定您是否可以仅使用正则表达式来处理它,如果是 utf-8 文件名,您还应该对文件名进行 urldecode。此外,它可以出现在namefilename 属性下。这是我的解决方案:

function getFilenameFromDisposition($value)
{
    $value = trim($value);

    if (strpos($value, ';') === false) {
        return null;
    }

    list($type, $attr_parts) = explode(';', $value, 2);

    $attr_parts = explode(';', $attr_parts);
    $attributes = array();

    foreach ($attr_parts as $part) {
        if (strpos($part, '=') === false) {
            continue;
        }

        list($key, $value) = explode('=', $part, 2);

        $attributes[trim($key)] = trim($value);
    }

    $attrNames = ['filename*' => true, 'filename' => false];
    $filename = null;
    $isUtf8 = false;
    foreach ($attrNames as $attrName => $utf8) {
        if (!empty($attributes[$attrName])) {
            $filename = trim($attributes[$attrName]);
            $isUtf8 = $utf8;
            break;
        }
    }
    if ($filename === null) {
        return null;
    }

    if ($isUtf8 && strpos($filename, "utf-8''") === 0 && $filename = substr($filename, strlen("utf-8''"))) {
        return rawurldecode($filename);
    }
    if (substr($filename, 0, 1) === '"' && substr($filename, -1, 1) === '"') {
        $filename = substr($filename, 1, -1);
    }

    return $filename;
}

测试:

attachment; filename*=utf-8''%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82.doc -> привет.doc
attachment; filename="hello.pdf" -> hello.pdf
attachment; filename=hello.png -> hello.png
inline; name=field1 -> null
attachment; -> null
attachment; filename= -> null

【讨论】:

  • Content-Disposition 中没有指定的“文件”属性。
  • @JulianReschke Thx,你是对的,这是评论中的错误,我刚刚修复了它。代码 sn -p 是正确的,它检查 namefilename 属性。
  • "name" 也没有指定。你真的只需要“文件名”:
  • @JulianReschke 已编辑,再次感谢,你是对的:name 有完全不同的含义。
  • 上面的代码可能会被“;”绊倒在带引号的字符串参数中。
【解决方案3】:

尝试简单地使用向后看

$str = "attachment; filename*=UTF-8''test.rar";

preg_match('/(?<=\')[a-z-A-Z0-9 -,.()%]*/', $str, $matches);

print_r($matches);

演示https://www.regex101.com/r/yO9nQ4/1

【讨论】:

  • 不匹配:attachment; filename*=UTF-8''Epost%20-test.part01.rar 我想你想编辑你的答案
  • 好的,我会做的...@Rizier123
【解决方案4】:

您需要提供更多信息。 第一部分总是一样的吗?文件名总是在末尾,就在 '' 之后?

--编辑--

如果您只需要删除第一部分,请不要使用正则表达式

$str = "attachment; filename*=UTF-8''test.rar";

$filename = substr($str, 29);  

【讨论】:

  • Uii 是否有一些我在此评论中看不到的隐藏答案?
  • 文件名总是在最后。我需要删除attachment; filename*=UTF-8''
  • 以上不是问题的答案,您应该在评论中添加此内容
猜你喜欢
  • 1970-01-01
  • 2012-09-28
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多