如何在PHP中通过重复字符分割字符串


How to split a string by repeated characters in PHP?

我正在尝试将一个带有二进制的字符串分割成一个重复字符数组。

例如,用这个函数分割的10001101数组为:

    $arr[0] = '1';
    $arr[1] = '000';
    $arr[2] = '11';
    $arr[3] = '0';
    $arr[4] = '1';

(我试图让自己清楚,但如果你仍然不明白,我的问题是一样的,但对于PHP,而不是Python)

<?php
$s = '10001101';
preg_match_all('/((.)'2*)/',$s,$m);
print_r($m[0]);
/*
Array
(
    [0] => 1
    [1] => 000
    [2] => 11
    [3] => 0
    [4] => 1
)
*/
?>

匹配1或更多的重复字符序列。regex将主题字符存储到第二个捕获组((.),存储为$m[1])中,而第一个捕获组包含整个重复序列(((.)'2*),存储为$m[0])。对于preg_match_all,它在整个字符串上全局执行此操作。这可以应用于任何字符串,例如'aabbccddee'。如果您希望只使用01,那么在第二个捕获组中使用[01]而不是.

请记住$m可能为空,在使用它之前先检查结果是否存在,即isset($m[0])

我在想这样的事情。代码没有经过测试,我直接写在注释里,所以可能会有一些错误,你可以调整。

$chunks = array();
$index = 0;
$chunks[$index] = $arr[0];
for($i = 1; $i < sizeof($arr) - 1; $i++) {
  if( $arr[$i] == $arr[$i-1] ) {
    $chunks[$index] .= $arr[$i];
  } else {
    $index++;
    $chunks[$index] = $arr[$i];
  }
}

我不会在模式中查找字符串结束符。

最简洁地说,捕获第一个出现的字符,然后允许捕获的字符重复零次或多次,然后使用'K重新启动fullstring匹配,以便在爆炸中没有字符丢失。

代码(演示):

var_export(
    preg_split('~(.)'1*'K~', '10001101', 0, PREG_SPLIT_NO_EMPTY)
);
输出:

array (
  0 => '1',
  1 => '000',
  2 => '11',
  3 => '0',
  4 => '1',
)

如果您不关心正则表达式,这里有一种遍历每个字符的方法,将其与前一个字符进行比较,并有条件地将重复字符连接到引用变量。

代码:(Demo)…与第一个代码片段

结果相同
$array = [];
$lastChar = null;
foreach (str_split('10001101') as $char) {
    if ($char !== $lastChar) {
        unset($ref);
        $array[] = &$ref;
        $ref = $char;
        $lastChar = $char;
    } else {
        $ref .= $char;
    }
}
var_export($array);