【问题标题】:preg_grep multiple words without orderpreg_grep 多个单词无序
【发布时间】:2013-05-30 02:30:53
【问题描述】:

我正在尝试使用 preg_grep 在数组中搜索包含 all 我的模式中列出的单词的任何值,以任何顺序。

假设我要搜索的词如下: 苹果 梨 香蕉

我试过了:

$result = preg_grep("/(apple|pear|banana)/i", $array);

返回包含三个单词中任何一个的字符串

$result = preg_grep("/(apple.*pear.*banana)/i", $array);

返回包含所有 3 个的字符串,但它们必须按顺序排列。

如何执行无序的preg_grep?

【问题讨论】:

    标签: php grep


    【解决方案1】:

    在单个正则表达式中进行“全部匹配”是很困难的——您需要枚举所有可能的顺序,即 O(n!)。相反,请使用array_filter():

    array_filter($array, function($x) {
        return preg_match('/apple/', $x) && preg_match('/pear/', $x) && preg_match('/banana/', $x);
    });
    

    【讨论】:

    • 感谢您的回答。我之前没有遇到过数组之间的 && 运算符,这是如何工作的?另外,如何将其扩展为使用单词数组?
    • 我没有在数组之间使用它。 preg_match() 返回真或假,不是数组。
    • 对不起,我完全误读了我以为你还在使用 preg_grep。为愚蠢的问题道歉。
    • 我在尝试扩展它以跨“单词”数组工作时遇到了麻烦(我意识到这超出了原始问题的范围),因为似乎没有一种简单的方法可以通过回调函数的数组,除了创建另一个类:stackoverflow.com/questions/5482989/…
    • 你应该可以通过闭包和use 选项来做到这一点。
    【解决方案2】:

    您也可以尝试使用前瞻模式..

    preg_grep("/(?=.*apple)(?=.*pear)(?=.*banana).*/",$array);

    【讨论】:

    • 我认为前瞻不允许变长模式。
    • 我一直使用这些类型的模式来验证密码格式..(即至少 1 个数字、1 个大写字母等)
    • 我选择了这个解决方案,因为我分析了这个和 Barmar 的解决方案(使用 xdebug)并发现对于我的 4000 个字符串和 3 个搜索词的列表,这比执行 array_filter 和多个 grep 快 4 倍.
    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    相关资源
    最近更新 更多