strpos()有多针?

Nik*_*kov 21 php full-text-search full-text-indexing strpos

我正在寻找像strpos()这样的函数,它有两个显着的区别:

  1. 能够接受多针.我的意思是成千上万针.
  2. 搜索大海捞针中所有针的出现次数并返回一系列起始位置.

当然,它必须是一种有效的解决方案,而不仅仅是每根针的循环.我搜索了这个论坛,并且有类似的问题,例如:

但是我们正在寻找它们.我使用strpos只是为了更好地说明我的问题,可能有一些完全不同的东西必须用于此目的.

我知道Zend_Search_Lucene,我感兴趣的是它是否可以用来实现这个以及如何(只是一般的想法)?

非常感谢您的帮助和时间!

Bai*_*ker 7

以下是我的策略的一些示例代码:

function strpos_array($haystack, $needles, $offset=0) {
    $matches = array();

    //Avoid the obvious: when haystack or needles are empty, return no matches
    if(empty($needles) || empty($haystack)) {
        return $matches;
    }

    $haystack = (string)$haystack; //Pre-cast non-string haystacks
    $haylen = strlen($haystack);

    //Allow negative (from end of haystack) offsets
    if($offset < 0) {
        $offset += $heylen;
    }

    //Use strpos if there is no array or only one needle
    if(!is_array($needles)) {
        $needles = array($needles);
    }

    $needles = array_unique($needles); //Not necessary if you are sure all needles are unique

    //Precalculate needle lengths to save time
    foreach($needles as &$origNeedle) {
        $origNeedle = array((string)$origNeedle, strlen($origNeedle));
    }

    //Find matches
    for(; $offset < $haylen; $offset++) {
        foreach($needles as $needle) {
            list($needle, $length) = $needle;
            if($needle == substr($haystack, $offset, $length)) {
                $matches[] = $offset;
                break;
            }
        }
    }

    return($matches);
}
Run Code Online (Sandbox Code Playgroud)

我已经在上面实施了一个简单的强力方法,可以使用针和干草堆的任何组合(不仅仅是单词).对于可能更快的算法,请查看:


其他方案

function strpos_array($haystack, $needles, $theOffset=0) {
    $matches = array();

    if(empty($haystack) || empty($needles)) {
        return $matches;
    }

    $haylen = strlen($haystack);

    if($theOffset < 0) {  // Support negative offsets
        $theOffest += $haylen;
    }

    foreach($needles as $needle) {
        $needlelen = strlen($needle);
        $offset = $theOffset;

        while(($match = strpos($haystack, $needle, $offset)) !== false) {
            $matches[] = $match;
            $offset = $match + $needlelen;
            if($offset >= $haylen) {
                break;
            }
        }
    }

    return $matches;
}
Run Code Online (Sandbox Code Playgroud)


小智 7

尝试preg匹配多个

if (preg_match('/word|word2/i', $str))
Run Code Online (Sandbox Code Playgroud)

检查多个strpos值


TJH*_*vel 0

您可以使用正则表达式,它们支持 OR 运算。然而,与 strpos 相比,这会使其相当慢。