Php 如何将基本一致的文件名解析为有意义的部分?

Php 如何将基本一致的文件名解析为有意义的部分?,php,regex,filenames,text-parsing,preg-split,Php,Regex,Filenames,Text Parsing,Preg Split,我有如下文件名: 1234_56_78 A_FAIRLY_SHORT_TITLE_D.pdf 幸运的是,文件命名非常一致,但我不能绝对保证有人没有在应该使用下划线的地方使用空格 考虑到这一点,我想解析字符串并提取以下细节: $project_no = '1234 $series_no = '56 $sheet_no = '78' $revision = 'D' $title = 'A Fairly Short Title' 目前,我使用以下信息获取此信息: $filename = $_FI

我有如下文件名:

1234_56_78 A_FAIRLY_SHORT_TITLE_D.pdf
幸运的是,文件命名非常一致,但我不能绝对保证有人没有在应该使用下划线的地方使用空格

考虑到这一点,我想解析字符串并提取以下细节:

$project_no = '1234
$series_no = '56
$sheet_no = '78'
$revision = 'D'
$title = 'A Fairly Short Title' 
目前,我使用以下信息获取此信息:

$filename = $_FILES['file']['name'][$i];
$filename = preg_replace('/\\.[^.\\s]{3,4}$/', '', $filename);
$parts = preg_split( "(_| )", $filename );
$project_no = $parts[0];
$series_no = $parts[1];
$sheet_no = $parts[2];
$revision = end($parts);
$title
就是删除
$parts[0]
$parts[1]
$parts[2]
end($parts)
后剩下的所有内容,但我应该如何表达呢

我想我可以用

$title = implode(' ',\array_diff_key($parts, [0,1,2,end($parts)]));
但这不会删除末尾的
$revision

$title = FLOOR AS PROPOSED D
我遗漏了什么?我是否不必要地过于复杂化了?

这两个阵列的关键比较。只移动数组的内部指针,实际上是无用的,因为它返回的值不能用于计算两个数组键之间的差

当前比较的行为如下

array_diff_key([0,1,2,3,4,5,6,7], [0,1,2,'D'])
从关键方面看,它如下所示:

因此,
内爆
的最终结果是
4,5,6,7
键值的串联

要将第二个参数数组值设置为键,可以使用以下表达式将键设置为值,将值设置为键:

$title = implode(' ',\array_diff_key($parts, array_flip([0,1,2,count($parts)-1])));

演示:

我担心你把这件事复杂化了。我认为单个
preg_match()
调用是解析字符串的最直接的方法

看起来您从中获取了正则表达式模式,以从文件名中修剪扩展名;但是,如果单个非正则表达式函数具有相同的用途,我建议使用正则表达式函数

pathinfo($filename', PATHINFO_FILENAME)
既然已经删除了扩展,那么让我们继续分析

代码:()

输出:

array (
  'project_no' => '1234',
  'series_no' => '56',
  'sheet_no' => '78',
  'title' => 'A FAIRLY SHORT TITLE',
  'revision' => 'D',
)

如果您在使用
preg_split()
时死气沉沉,那么该模式将变得非常简单,但还需要做一些清理工作

代码:()

他们是你的朋友。
$filename = '1234_56_78 A_FAIRLY_SHORT_TITLE_D.pdf';
preg_match('~([^ _]+)[ _]([^ _]+)[ _]([^ _]+)[ _](.+)[ _](\S)~', pathinfo($filename, PATHINFO_FILENAME), $m);

var_export([
    'project_no' => $m[1],
    'series_no' => $m[2],
    'sheet_no' => $m[3],
    'title' => str_replace('_', ' ', $m[4]),
    'revision' => $m[5],
]);
array (
  'project_no' => '1234',
  'series_no' => '56',
  'sheet_no' => '78',
  'title' => 'A FAIRLY SHORT TITLE',
  'revision' => 'D',
)
$filename = '1234_56_78 A_FAIRLY_SHORT_TITLE_D.pdf';
$m = preg_split('~ |_~', pathinfo($filename, PATHINFO_FILENAME));
$revision = array_pop($m);

var_export([
    'project_no' => $m[0],
    'series_no' => $m[1],
    'sheet_no' => $m[2],
    'title' => implode(' ', array_slice($m, 3)),
    'revision' => $revision,
]);
// same output as earlier snippet