PHP preg_replace正则表达式问题:文件路径处理未达预期
解决正则替换路径时的贪婪匹配问题
你的原正则preg_replace('/\/[\s\S]+?_/', '/', $currentFile)之所以出错,核心原因是贪婪匹配在搞鬼:[\s\S]+会尽可能抓取从第一个/到最后一个_之间的所有内容,直接把路径的大部分都替换掉了,完全不符合预期。
你的需求拆解
需要移除路径里两类特定前缀:
- 固定长度的数字前缀(比如
1010_,4位数字加下划线) - 自定义前缀(比如
productsheet_、fish-cb_这类,不含下划线的字符加下划线)
正确的解决方案
方案1:分步替换(直观易维护)
先处理数字前缀,再处理自定义前缀,逻辑更清晰:
// 移除4位数字+下划线的前缀 $currentFile = preg_replace('/\/\d{4}_/', '/', $currentFile); // 移除最后一段的自定义前缀(避免误匹配其他路径段) $currentFile = preg_replace('/\/[^_]+_(?=[^\/]+$)/', '/', $currentFile);
测试你的示例路径:
原路径:/public_html/ftp/Products/1010_Air+Cooled+Condenser/productsheet_Rotary+Drum+Dryer+BR.pdf
第一步替换后:/public_html/ftp/Products/Air+Cooled+Condenser/productsheet_Rotary+Drum+Dryer+BR.pdf
第二步替换后:/public_html/ftp/Products/Air+Cooled+Condenser/Rotary+Drum+Dryer+BR.pdf
完美符合预期!
方案2:合并成单个正则(简洁高效)
如果想一步到位,可以把两种情况合并到一个正则里:
$currentFile = preg_replace('/\/(?:\d{4}|[^_]+)_(?=[^\/]+$)?/', '/', $currentFile);
正则细节解释:
\/:匹配路径中的斜杠(?:\d{4}|[^_]+):非捕获组,匹配「4位数字」或「任意不含下划线的字符」_:匹配前缀末尾的下划线(?=[^\/]+$)?:可选的正向预查,确保只替换最后一段的自定义前缀(如果需要替换所有路径段的这类前缀,可以去掉这个部分)
原正则出错的根源
原正则里的[\s\S]+是贪婪模式,会从第一个/开始,一直匹配到路径中最后一个_的位置,直接把/public_html/ftp/Products/1010_Air+Cooled+Condenser/productsheet整个替换成/,结果自然完全偏离你的需求。
内容的提问来源于stack exchange,提问作者Bart Ros
相关产品推荐
相关产品推荐

