简体   繁体   English

PHP (preg_replace) 正则表达式从文件名中剥离图像大小

[英]PHP (preg_replace) regex strip image sizes from filename

I'm working on a open-source plugin for WordPress and frankly facing an odd issue.我正在为 WordPress 开发一个开源插件,坦率地说,我遇到了一个奇怪的问题。

Consider the following filenames:考虑以下文件名:

/wp-content/uploads/buddha_-800x600-2-800x600.jpg
/wp-content/uploads/cutlery-tray-800x600-2-800x600.jpeg
/wp-content/uploads/custommade-wallet-800x600-2-800x600.jpeg
/wp-content/uploads/UI-paths-800x800-1.jpg

The current regex I have:我目前的正则表达式:

(-[0-9]{1,4}x[0-9]{1,4}){1}

This will remove both matches from the filename, for example buddha_-800x600-2-800x600.jpg will become buddha_-2.jpg which is invalid.这将从文件名中删除两个匹配项,例如buddha_-800x600-2-800x600.jpg将变为无效的 buddha_-2.jpg

I have tried a variety of regex:我尝试了多种正则表达式:

.*(-\d{1,4}x\d{1,4}) // will trip out everything
(-\d{1,4}x\d{1,4}){1}|.*(-\d{1,4}x\d{1,4}){1} // same as above
(-\d{1,4}x\d{1,4}){1}|(-\d{1,4}x\d{1,4}){1} // will strip out all size matches

Unfortunately my knowledge with regex is quite limited, can someone advise how to achieve the goal please?不幸的是,我对正则表达式的了解非常有限,有人可以建议如何实现目标吗?

The goal is to remove only what is relevant, which would result in:目标是只删除相关的内容,这将导致:

/wp-content/uploads/buddha_-800x600-2.jpg
/wp-content/uploads/cutlery-tray-800x600-2.jpeg
/wp-content/uploads/custommade-wallet-800x600-2.jpeg
/wp-content/uploads/UI-paths-1.jpg

Much appreciated!非常感激!

You can use a capture group with a backreference to match strings where there are 2 of the same parts and replace that with a single part.您可以使用带有反向引用的捕获组来匹配具有 2 个相同部分的字符串,并将其替换为单个部分。

Or match the dimensions to be removed.或匹配要删除的尺寸。

((-\d+x\d+)-\d+)\2|-\d+x\d+
  • ( Capture group 1 (捕获组 1
    • (-\d+x\d+) Capture group 2 , match - 1+ digits x and 1+ digits (-\d+x\d+)捕获组 2 ,匹配- 1+ 数字x和 1+ 数字
    • -\d+ Match - and 1+ digits -\d+匹配 - 和 1+ 位
  • )\2 Close group 2 followed by a backreference to what is captured in grouip 1 )\2关闭第 2 组,然后是对第 1 组中捕获的内容的反向引用
  • | Or或者
  • -\d+x\d+ Match the dimensions format -\d+x\d+匹配维度格式

Regex demo |正则表达式演示| Php demo Php演示

For example例如

$pattern = '~((-\d+x\d+)-\d+)\2|-\d+x\d+~';
$strings = [
    "/wp-content/uploads/buddha_-800x600-2-800x600.jpg",
    "/wp-content/uploads/cutlery-tray-800x600-2-800x600.jpeg",
    "/wp-content/uploads/custommade-wallet-800x600-2-800x600.jpeg",
    "/wp-content/uploads/UI-paths-800x800-1.jpg",
];

foreach ($strings as $s) {
    echo  preg_replace($pattern, '$1', $s) . PHP_EOL;
}

Output Output

/wp-content/uploads/buddha_-800x600-2.jpg
/wp-content/uploads/cutlery-tray-800x600-2.jpeg
/wp-content/uploads/custommade-wallet-800x600-2.jpeg
/wp-content/uploads/UI-paths-1.jpg

I would try something like this.我会尝试这样的事情。 You can test it yourself.你可以自己测试一下。 Here is the code:这是代码:

$a = [
     '/wp-content/uploads/buddha_-800x600-2-800x600.jpg',
     '/wp-content/uploads/cutlery-tray-800x600-2-800x600.jpeg',
     '/wp-content/uploads/custommade-wallet-800x600-2-800x600.jpeg',
     '/wp-content/uploads/UI-paths-800x800-1.jpg'
];
            
foreach($a as $img) 
    echo preg_replace('#-\d+x\d+((-\d+|)\.[a-z]{3,4})#i', '$1', $img).'<br>';

It checks for ending -(number)x(number)(dot)(extension)它检查结尾 -(number)x(number)(dot)(extension)

This is a clear case of « Match the rejection, revert the match ».这是 « 匹配拒绝,恢复匹配 » 的明显案例。 So, you just have to think about the pattern you are searching to remove:所以,你只需要考虑你要搜索删除的模式:

[0-9]+x[0-9]+

which is simply (much condensed):这很简单(非常浓缩):

\d+x\d+

The next step is to build the groups extractor:下一步是构建组提取器:

^(.*[^0-9])[0-9]+x[0-9]+([^x]*\.[a-z]+)$

We added the extension of the file as a suffix for the extract.我们添加了文件的扩展名作为提取的后缀。 The rejection of the "x" char is a (bad…) trick to ensure the match of the last size only.拒绝“x”字符是确保仅匹配最后一个大小的(坏...)技巧。 It won't work in the case of an alphanumeric suffix between the size and the extension ( toto-800x1024-ex.jpg for instance).它不适用于大小和扩展名之间的字母数字后缀(例如toto-800x1024-ex.jpg )。

And then, the replacement string:然后,替换字符串:

$1$2

For clarity of course, we are only working on a successfully extracted filename.当然,为了清楚起见,我们只处理成功提取的文件名。 But if you want to treat the whole string, the pattern becames:但是如果你想处理整个字符串,模式就变成了:

^/(.*[^0-9])[0-9]+x[0-9]+([^/x]*\.[a-z]+)$

If you want to split the filename and the folder name:如果要拆分文件名和文件夹名:

^/(.*/)([^/]+[^0-9])[0-9]+x[0-9]+([^/x]*)(\.[a-z]+)$
^/(.*/)([^/]+\D)\d+x\d+([^/x]*)(\.[a-z]+)$
$folder=$1;
$filename="$1$2";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM