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

时间:2014-05-28 19:20:16

标签: php regex

我正在实施"标签"我们的定制产品管理系统中的功能。每个产品都有一个逗号分隔的标签列表。我们有一个"标签搜索"带复选框。用户可以检查多个标签,它将使用带有所有选定标签的ajax进行过滤,因此所有标签都需要匹配在一起。实施例。

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

当选中上述标签进行过滤时,我希望仅返回#1,#2,#3,因为这些产品的product-tags列中列出了给定的标签。

我正在尝试通过在用户检查标记时动态创建正则表达式来使用正则表达式。为了符合条件,产品必须检查所有标签。我这样生成这个:

   <?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);
         }
       }
    ?>

我没有得到这样做的预期结果。什么是我能得到预期结果的最佳方式。我对正则表达式不太好,但我正在学习。

4 个答案:

答案 0 :(得分:1)

我假设标签以逗号分隔的字符串存储在数组中。如果是这种情况,您可以使用explode()将它们拆分为单个数组,然后遍历数组并使用array_intersect()查看是否有任何子数组全部< / strong> $search数组中的值:

$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);
    }
}

这种方法不仅效率高,而且更灵活。如果您有多个条件需要检查,那将不会有问题。如果你是用正则表达式来做这件事的话,你很难制作正则表达式,并且很可能比这个简单的分割和速度慢得多。循环解决方案。

对于问题中的标签,这将不返回任何内容 - $products数组将为空。

Demo

答案 1 :(得分:1)

如果你仍然想要使用正则表达式,我建议使用像

这样的正则表达式
Tag2(,.*)?$|Tag1(,.*)?$/i

查看实时示例here

使用新规格,您必须使用正向前瞻

(?=(((Tag1|Tag2|Tag3)(,.*)?$)))

查看实时示例here

答案 2 :(得分:0)

我认为你的正则表达式有2个小细节需要考虑。 1 - 缺少第一个分隔符/ 2 - 在括号中分组您想要选择其中一个的选项

$regex = "/\b(" . $tag1 . "|" . $tag2 . "|" . $tag3 . ")\b/i";


try with this code to see my result.
<?php
 $tag1 = 'Tag1';
 $tag2 = 'Tag2';
 $tag3 = 'Tag3';

$arr = array();
$arr["#1-product-tags"] = "Tag3,Tag10,Tag2";
$arr["#2-product-tags"] = "Tag1,Tag3,Tag10";
$arr["#3-product-tags"] = "Tag5,Tag1,Tag3";
$arr["#4-product-tags"] = "Tag8,Tag4,Tag20";
$arr["#5-product-tags"] = "Tag20,Tag100,Tag500";
var_dump($arr);

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

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

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

答案 3 :(得分:0)

我终于想出了一个有效的解决方案。 /^(?=.*?Tag1)(?=.*?Tag2)(?=.*?Tag3).*$/就像一个魅力