在一个字符串中查找所有重叠的子串

4

你好,我正在尝试在一个字符串中找到所有重叠的子字符串,这是我的代码,它只能找到非重复的ACA。

$haystack = "ACAAGACACATGCCACATTGTCC";
$needle = "ACA";
echo preg_match_all("/$needle/", $haystack, $matches);
2个回答

3
您正在使用`echo`打印`preg_match_all`的返回值。也就是说,您只显示了找到的匹配次数。您可能想要做的是像这样使用`print_r($matches);`:
$haystack = "ACAAGACACATGCCACATTGTCC";
$needle = "ACA";
preg_match_all("/$needle/", $haystack, $matches);
print_r($matches);

输出:

Array
(
    [0] => Array
        (
            [0] => ACA
            [1] => ACA
            [2] => ACA
        )

)

演示

如果您真正关心的是它仅计算了ACACA一次,那么有三件事情需要说:

  1. That's basically unavoidable with regex.
  2. You really shouldn't count this twice, as it's overlapping. It's not a true recurrence of the pattern.
  3. That said, if you want to count that twice, you could do so with something like this:

    echo preg_match_all("/(?=$needle)/", $haystack, $matches);
    

    Output:

    4
    

    Demo


但我也需要重叠的ACA,这是我的问题。 - lolsharp
//TT 在 TTT 中出现了两次! - lolsharp
@lolsharp (?=...) 是所谓的“正向预查”。它的意思是:“看一下接下来的内容是否为 xyz,但不要移动光标。” 它允许我们找到每个包含 ACA(或任何 $needle)的位置,而不“消耗”这三个字符。下一个匹配只能再往前移动一个字符。 - elixenide

0

这里有一个脚本,可以找到所有子字符串的出现次数,包括重叠的。

    $haystack = "ACAAGACACATGCCACATTGTCC";
    $needle   = "ACA";

    $positions    = [];
    $needle_len   = strlen($needle);
    $haystack_len = strlen($haystack);

    for ($i = 0; $i <= $haystack_len; $i++) {
        if( substr(substr($haystack,$i),0,$needle_len) == $needle){
            $positions[]=$i;
        }
    }
    print_r($positions);

输出:数组(0,5,7,14)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接