duanqun7761 2014-05-28 19:20
浏览 351
已采纳

使用正则表达式将多个完整单词与php匹配

I'm implementing a "Tags" feature in our custom product management system. Each product has a comma seperated list of tags associated. We have a "tag search" with check boxes. The user can check multiple tags and it will filter with ajax with all the selected tags, so all tags need to be matched together. Example.

Tags: Tag1,Tag2,Tag3

#1-product-tags: Tag3,Tag10,Tag2
#2-product-tags: Tag1,Tag3,Tag10
#3-product-tags: Tag5,Tag1,Tag3
#4-product-tags: Tag8,Tag4,Tag20
#5-product-tags: Tag20,Tag100,Tag500

When filtering with the above tags checked, I expect to return #1,#2,#3 only because the given tags are listed in the product-tags column of these products.

Im currently trying to use regular expressions by dynamically creating a regex when the user checks the tags. In order to qualify as a match, the product must have all tags checked. Im generating this like so:

   <?php 
       //empty collection array to fill with product loop
       $collection = array();

       //dynamically generated regex
       $regex = "\b" . $tag1 . "|" . $tag2 . "|" . $tag3 . "\b/i";

       //loop through each product and throw matches to collection
       foreach($products as $product) {
         if(preg_match($regex,$product->tags)) {
            array_push($collection,$product);
         }
       }
    ?>

I am not getting the expected result doing it this way. What is the best way I can get my expected result. Im not too great with Regular Expressions but I am learning.

  • 写回答

4条回答 默认 最新

  • doouzlrvb01417498 2014-05-28 19:31
    关注

    I'm assuming the tags are stored in an array as comma-separated strings. If that's the case, you can split them into individual arrays using explode() and then loop through the array and use array_intersect() to see if any of the sub-arrays have all the values in the $search array:

    $search = ['Tag1', 'Tag2', 'Tag3'];
    
    $taglist = array_map(function ($v) { return explode(',', $v); }, $tags);
    
    foreach ($taglist as $sub) {
        if (count(array_intersect($sub, $search)) == count($search)) {
            $products[] = implode(',', $sub);
        }
    }
    

    Not only this approach is efficient, it is more flexible. It will not be a problem if you have multiple conditions to check for. If you were to do this with a regex, you'd have a hard time crafting the regex and chances are it will be a lot slower than this simple split & loop solution.

    For the tags in the question, this would return nothing — $products array would be empty.

    Demo

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备
  • ¥20 delta降尺度方法,未来数据怎么降尺度
  • ¥15 c# 使用NPOI快速将datatable数据导入excel中指定sheet,要求快速高效
  • ¥15 再不同版本的系统上,TCP传输速度不一致
  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题