🔖

【PHP】正規表現でマッチした結果を配列として返す関数を定義する

2024/07/16に公開

mb_ereg 系の関数には preg_match_all に相当するものがないので自作することにした。Python では re.findallre.finditer (イテレーターを返す)が用意されている。Ruby では String.scan が用意されている

$str = "ハ\u{309A}ハ\u{309A}と神";

var_dump(
    mb_ereg_findall($str, '\X')
);

foreach (mb_ereg_finditer($str, '\X') as $key => $value) {
    echo $key, ' ', $value, PHP_EOL;
}

function mb_ereg_findall(string $str, string $pattern): array {

    mb_ereg_search_init($str, $pattern);
    $ret = [];

    while (mb_ereg_search()) {
        $ret[] = mb_ereg_search_getregs()[0];
    }

    return $ret;
}

function mb_ereg_finditer(string $str, string $pattern): Generator {

    mb_ereg_search_init($str, $pattern);
    $key = 0;

    while (mb_ereg_search()) {
        yield $key => mb_ereg_search_getregs()[0];
        ++ $key;
    }
}

preg_match でも同等のことができる

$str = "ハ\u{309A}ハ\u{309A}と神";

var_dump(
    preg_findall($str, '/\X/us')
);

foreach (preg_finditer($str, '/\X/us') as $key => $value) {
    echo $key, ' ', $value, PHP_EOL;
}

function preg_findall(string $str, string $pattern): array {

    $ret = [];
    $offset = 0;

    while (preg_match($pattern, $str, $matches, 0, $offset)) {
        $ret[] = $matches[0];
        $offset += strlen($matches[0]);
    }

    return $ret;
}

function preg_finditer(string $str, string $pattern): Generator {
    $key = 0;
    $offset = 0;

    while (preg_match($pattern, $str, $matches, 0, $offset)) {
        yield $key => $matches[0];
        ++$key;
        $offset += strlen($matches[0]);
    }
}

Discussion