Как preg_match_all на немецких умлаутсах? - PullRequest
2 голосов
/ 11 мая 2019

Если текст имеет Umlauts на немецком языке [äöü], результат preg_match_all имеет неправильные смещения (кажется, что каждый Umlaut увеличивает смещение на 1)

Мне нужна позиция каждого слова, потому что они будут заменены другими строками. С этим инструментом https://regex101.com/r/UosqVD/2 все заработало, совпадения имеют правильное начальное значение.

$pattern = "~\b\w+\b~u";
$text = "Käthe würde gerne wählen.";
if (preg_match_all($pattern, $text, $matches, PREG_OFFSET_CAPTURE)) {
    foreach ($matches[0] as $m) {
        echo $m[0]."; ".$m[1]."; ".mb_strlen($m[0], "utf-8")."<br />";
    }
}

Text; Start, Length<br>
Käthe; 0; 5<br>
würde; 7; 5<br>
gerne; 14; 5<br>
wählen; 20; 6<br>

1 Ответ

1 голос
/ 11 мая 2019

Документация PHP содержит функцию mb_preg_match_all(), написанную пользователем, которая, кажется, соответствует вашим потребностям:

function mb_preg_match_all($ps_pattern, $ps_subject, &$pa_matches, $pn_flags = PREG_PATTERN_ORDER, $pn_offset = 0, $ps_encoding = NULL) {
    // WARNING! - All this function does is to correct offsets, nothing else:
    //
    if (is_null($ps_encoding))
        $ps_encoding = mb_internal_encoding();

    $pn_offset = strlen(mb_substr($ps_subject, 0, $pn_offset, $ps_encoding));
    $ret = preg_match_all($ps_pattern, $ps_subject, $pa_matches, $pn_flags, $pn_offset);

    if ($ret && ($pn_flags & PREG_OFFSET_CAPTURE))
        foreach($pa_matches as &$ha_match)
            foreach($ha_match as &$ha_match)
                $ha_match[1] = mb_strlen(substr($ps_subject, 0, $ha_match[1]), $ps_encoding);
        //
        // (code is independent of PREG_PATTER_ORDER / PREG_SET_ORDER)

    return $ret;
}
...