通过 PHP 从内容配置中提取文件名
Extracting filename from content disposition via PHP
我需要一个正则表达式来从以下字符串中提取文件名(包括文件扩展名):
attachment; filename*=UTF-8''test.rar
或者像这样
attachment; filename*=UTF-8''Epost%20-test.part01.rar
目标:
test.rar
Epost%20-test.part01.rar
我该怎么做?
注意:我正在使用 preg_match 进行提取
您需要提供更多信息。
第一部分总是一样的吗?文件名总是在末尾,就在 '' 之后吗?
--编辑--
如果您只需要删除第一部分,则不要使用正则表达式
$str = "attachment; filename*=UTF-8''test.rar";
$filename = substr($str, 29);
这应该适合你:
<?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
尝试简单地使用向后看
$str = "attachment; filename*=UTF-8''test.rar";
preg_match('/(?<=\')[a-z-A-Z0-9 -,.()%]*/', $str, $matches);
print_r($matches);
不确定您是否可以仅使用 regexpr 来处理它,如果是 utf-8 文件名,您还应该对文件名进行 urldecode。此外,它可以出现在 name
或 filename
属性下。这是我的解决方案:
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
我需要一个正则表达式来从以下字符串中提取文件名(包括文件扩展名):
attachment; filename*=UTF-8''test.rar
或者像这样
attachment; filename*=UTF-8''Epost%20-test.part01.rar
目标:
test.rar
Epost%20-test.part01.rar
我该怎么做?
注意:我正在使用 preg_match 进行提取
您需要提供更多信息。 第一部分总是一样的吗?文件名总是在末尾,就在 '' 之后吗?
--编辑--
如果您只需要删除第一部分,则不要使用正则表达式
$str = "attachment; filename*=UTF-8''test.rar";
$filename = substr($str, 29);
这应该适合你:
<?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
尝试简单地使用向后看
$str = "attachment; filename*=UTF-8''test.rar";
preg_match('/(?<=\')[a-z-A-Z0-9 -,.()%]*/', $str, $matches);
print_r($matches);
不确定您是否可以仅使用 regexpr 来处理它,如果是 utf-8 文件名,您还应该对文件名进行 urldecode。此外,它可以出现在 name
或 filename
属性下。这是我的解决方案:
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