如何使preg_replace处理文件名忽略,文件扩展名?

时间:2016-12-23 11:53:10

标签: php regex preg-replace

我的文件名为Dona&ld #Duck .jpg。我想在.jpg之前替换所有特殊字符或用_(下划线)替换任何文件扩展名。 输出应为Don_a_ld__Duck__.jpg

如何使用preg_replace实现此目的?我做了如下。

$fileName ='Don.a&ld #Duck .jpg';
$fileName = trim($fileName);
$fileExtension = substr($fileName,-4);
$fileName = substr($fileName,0,-4); // file name without extension
echo $filename = preg_replace('/[^a-z0-9]/i', '_', $fileName).$fileExtension; 

我不想单独附加文件扩展名。

2 个答案:

答案 0 :(得分:2)

您可以使用前瞻性正则表达式:

$fileName = preg_replace('/\W(?=.*\.[^.]+$)/', '_', $fileName);
//=> Dona_ld__Duck__.jpg

\W(?=.*\.[^.]+$)将匹配DOT和任何扩展名后面的非单词字符。

RegEx Demo

答案 1 :(得分:2)

使用以下具有保护最后一个点的负前瞻的解决方案:

$fileName ='Don.a&ld #Duck .jpg';
echo $filename = preg_replace('/[^a-z0-9](?![^.]*$)/i', '_', $fileName);
                                          ^^^^^^^^^ 

请参阅PHP demo

如果特殊字符后面跟着一个点以外的0 +字符,那么(?![^.]*$)就会使匹配失败。

请注意,/[^a-z0-9]/i_匹配,并替换为_,这是一项冗余操作。您可以使用\W子模式避免它:

preg_replace('/\W(?![^.]*$)/', '_', $fileName)