如何将基本一致的文件名解析为有意义的部分?
How to parse a mostly consistent filename into meaningful parts?
我的文件名如下:
1234_56_78 A_FAIRLY_SHORT_TITLE_D.pdf
幸运的是,文件命名非常一致,但我不能绝对保证有人没有在应该使用下划线的地方使用 space。
考虑到这一点,我想解析字符串并提取以下详细信息:
$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
looks at key comparison of both arrays. end()
只是移动数组的内部指针,实际上没有用,因为从它返回的值不能用于计算两个数组键之间的差异。
当前比较行为
array_diff_key([0,1,2,3,4,5,6,7], [0,1,2,'D'])
看起来 关键 明智的是:
array_diff_key([0,1,2,3,4,5,6,7], [0,1,2,3])
因此,implode
的最终结果是 4,5,6,7
个键值的串联。
要将第二个参数数组值作为键,可以使用array_flip
将键作为值,将值作为键,表达式如下:
$title = implode(' ',\array_diff_key($parts, array_flip([0,1,2,count($parts)-1])));
我担心你把这个复杂化了。我认为单个 preg_match()
调用是解析字符串的最直接方式。
看起来您从文件名中获取了从 到 trim 扩展名的正则表达式模式;但是,当单个非正则表达式函数用于相同目的时,我建议使用正则表达式函数。
pathinfo($filename', PATHINFO_FILENAME)
既然已经删除了扩展,让我们继续解析。
代码:(Demo)
$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',
)
如果您对使用 preg_split()
很执着,那么该模式将变得非常简单,但还有更多工作要做。
代码:(Demo)
$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
我的文件名如下:
1234_56_78 A_FAIRLY_SHORT_TITLE_D.pdf
幸运的是,文件命名非常一致,但我不能绝对保证有人没有在应该使用下划线的地方使用 space。
考虑到这一点,我想解析字符串并提取以下详细信息:
$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
looks at key comparison of both arrays. end()
只是移动数组的内部指针,实际上没有用,因为从它返回的值不能用于计算两个数组键之间的差异。
当前比较行为
array_diff_key([0,1,2,3,4,5,6,7], [0,1,2,'D'])
看起来 关键 明智的是:
array_diff_key([0,1,2,3,4,5,6,7], [0,1,2,3])
因此,implode
的最终结果是 4,5,6,7
个键值的串联。
要将第二个参数数组值作为键,可以使用array_flip
将键作为值,将值作为键,表达式如下:
$title = implode(' ',\array_diff_key($parts, array_flip([0,1,2,count($parts)-1])));
我担心你把这个复杂化了。我认为单个 preg_match()
调用是解析字符串的最直接方式。
看起来您从文件名中获取了从 到 trim 扩展名的正则表达式模式;但是,当单个非正则表达式函数用于相同目的时,我建议使用正则表达式函数。
pathinfo($filename', PATHINFO_FILENAME)
既然已经删除了扩展,让我们继续解析。
代码:(Demo)
$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',
)
如果您对使用 preg_split()
很执着,那么该模式将变得非常简单,但还有更多工作要做。
代码:(Demo)
$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