如何使用数组中的 preg_grep 查找仅/更多指定字母的单词?

Posted

技术标签:

【中文标题】如何使用数组中的 preg_grep 查找仅/更多指定字母的单词?【英文标题】:How to find words with only/more specified letters using preg_grep in array? 【发布时间】:2018-05-22 12:10:00 【问题描述】:

我有用于从指定字母的数组中搜索单词的示例函数:

public static function getWords($words, $specifed_letters) 
 
    $pattern = is_array($specifed_letters) ? '/[' . implode("", 
    $specifed_letters) . ']/u' : '/[' .$specifed_letters. ']/u';
    $result = preg_grep($pattern, $array_words);
    return $result;

示例用法:

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"];
$result = getWords($words, $letters = ['l', 's']);

此示例将返回单词:apple, sample。 因为在这个词中有字母"l""s"

如何搜索单词中包含所有指定字母的单词?

例如,如果我添加到指定的字母"app",那么从单词数组中必须返回单词:app, apple

以及如何使用仅指定字母搜索单词。例如,我将在shuffled 变体"pap" 中写入单词"app"。以及我如何才能获得仅结果字 "app" without "apple"

【问题讨论】:

所以当两个ps 被作为输入时,您想在单词中查找两个ps 吗? 是的。查找有两个 p 的单词@revo 【参考方案1】:

您可以将单词字符拆分为数组并循环它们,并将指定字符串中的字符拆分为数组。

如果某个单词字符出现在指定字符串数组的字符中,则从两个数组中删除该字符。

循环完成后,验证指定字符串数组的字符中是否没有剩余字符。

$words = ["apple", "sample", "app", "justappgg", "тоҷик", "отабек", "баҳодурбек", "APELCIN", "API", "pap"];
mb_internal_encoding("UTF-8");

foreach ($words as $word) 
    $wordSplit = preg_split('//u', $word, null, PREG_SPLIT_NO_EMPTY);
    $strSplit = preg_split('//u', $str, null, PREG_SPLIT_NO_EMPTY);
    $wordSplit = array_filter($wordSplit, function ($x) use (&$strSplit) 
        if (in_array(strtolower($x), array_map('strtolower', $strSplit), true)) 
            $pos = array_search(strtolower($x), array_map('strtolower', $strSplit), true);
            unset($strSplit[$pos]);
            return false;
        
        return true;
    );
    if (count($strSplit) === 0) 
        echo "$word contains all letters of $str" . php_EOL;
    

Demo

【讨论】:

@Otabek 这可能是对代码Demo 的轻微重构。我还可以添加解释吗? 在这里我创建了新问题以在codereview中执行它【参考方案2】:

您可以使用 preg_grep。 如果您在正则表达式模式中将 [] 内的字母内爆,它应该查找该字母并在找到时返回该项目。

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"];
$letters = ['l', 's'];

$res = preg_grep("/[" . implode("", $letters) . "]/", $words); // pattern = "/[ls]/"
var_dump($res);

https://3v4l.org/UZTYZ

编辑 但是您问题的这一部分:以及如何仅使用指定字母搜索单词。例如,我将用洗牌变体“pap”写单词“app”。以及我如何才能在没有“apple”的情况下仅使用结果词“app”? 与您想要进行非常松散的搜索的第一部分完全相反。 您是否期待一个松散的和一个精确的结果数组?


您可以通过拆分字符串并对字母进行排序(在数组中)来进行精确匹配。 然后检查数组是否相互匹配。如果他们这样做,那么这是一个完全匹配。

$words = ["apple", "sample", "app", "тоҷик", "отабек", "баҳодурбек"]; 
$find = "pap";

$find = str_split($find);
sort($find);
foreach($words as $word)
    $temp = str_split($word);
    sort($temp);
    if($temp == $find)
        echo "match " . $word . "\n";
    

https://3v4l.org/WbTUK

【讨论】:

可以用数组的preg_grep实现吗? 我不这么认为,因为 preg_grep 是正则表达式。正则表达式是松散的搜索,特别是如果你不知道字母应该是什么顺序 好的。然后以您的示例为例,当输入为pap 时如何获得apple?因为在apple 中也有一个a 和两个p 字母。 可以用multisort对两个数组进行排序,用array_slice只比较找到的字符数。 3v4l.org/4Xqg8 我现在为ple 测试您的最后一个示例,但未找到单词。结果必须返回单词:applesample,因为它们有字母 ple

以上是关于如何使用数组中的 preg_grep 查找仅/更多指定字母的单词?的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中使用 preg_grep() 查找字符串之前或之后的字符

preg_grep 输出部分匹配

PHP preg_grep 多文件

preg_grep 不适用于多维数组[重复]

preg_grep() 期望参数 2 是数组,给定 null

php正则表达式之preg_grep