search

Home  >  Q&A  >  body text

特征匹配 - PHP 正则表达式 如何实现 反模式匹配

需求

如何用一行正则表达式进行排除匹配:不以/结尾且不以文件扩展名结尾的字符串
目的:访问的不是有扩展名文件名格式的、且结尾不是以“/”结尾,那么重定向到带“/”的网址。

示例

#符合
/images        ==> /images/
/uploads        ==> /uploads/
/register        ==> /register/
/images/uploads/201412    ==>    /images/uploads/201412/
/2014/222/jpg        ==>    /2014/222/jpg/

#不符合
/
/images/
/uploads/
/index.php
/images/test.jpg
/upload/my.1/test.jpg?a=1111&b=ddd&file=t.php
/index.html

正则

#如下是错误的
[^\/|\.[a-zA-Z]{2,4}]$ 

正则中括号貌似只能排除单个字符串,而不能排除一段字符串。如何排除一段字符串,如何实现如上的匹配

阿神阿神2902 days ago507

reply all(4)I'll reply

  • 天蓬老师

    天蓬老师2017-04-10 15:16:12

    $arr = [
        'home.inc/include.dir/a/', 
        'home.inc/include.dir/a.7z', 
        'home.inc/include.dir/a', 
    ];
    
    $arr = array_filter($arr, function($str) {
        return preg_match('/^(?:[^\/]*\/)*[^.]*[^\/]$/', $str); 
        // also preg_match('/^(?!.*?(?:\/|\.[^\/]+)$).*/', $str);
    });
    
    var_dump($arr); // array(1) { [2]=> string(22) "home.inc/include.dir/a" }
    

    reply
    0
  • 怪我咯

    怪我咯2017-04-10 15:16:12

    你需要的应该是「零宽断言」

    reply
    0
  • ringa_lee

    ringa_lee2017-04-10 15:16:12

    写了一个奇丑的,实在没办法写的更好看了

    ^.*(?<!\.\w{4})(?<!\.\w{3})(?<!\.\w{2})(?<!\/)$
    

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 15:16:12

    !preg_match('#(\/$)|(\/(?=[^\/]*\.[^\/]*$))#', $str)

    reply
    0
  • Cancelreply