PHP Conference Nagoya 2025

grapheme_extract

(PHP 5 >= 5.3.0, PHP 7, PHP 8, PECL intl >= 1.0.0)

grapheme_extractФункция для извлечения последовательности кластеров графем по умолчанию из текстового буфера, которая должна быть закодирована в UTF-8

Описание

Процедурный стиль

grapheme_extract(
    string $haystack,
    int $size,
    int $type = GRAPHEME_EXTR_COUNT,
    int $offset = 0,
    int &$next = null
): string|false

Функция для извлечения последовательности кластеров графем по умолчанию из текстового буфера, которая должна быть закодирована в UTF-8.

Список параметров

haystack

Строка для поиска.

size

Максимальное количество возвращаемых элементов на основе type.

type

Определяет тип единиц, на которые указывает параметр size:

  • GRAPHEME_EXTR_COUNT (по умолчанию) - size - это количество кластеров графемы для извлечения по умолчанию.
  • GRAPHEME_EXTR_MAXBYTES - size - максимальное количество возвращаемых байтов.
  • GRAPHEME_EXTR_MAXCHARS - size - это максимальное количество возвращаемых символов UTF-8.

offset

Начальная позиция haystack в байтах - если задано, оно должно быть нулём или положительным значением, которое меньше или равно длине haystack в байтах, либо отрицательным значением, отсчитываемым от конца haystack. Если offset не указывает на первый байт символа UTF-8, начальная позиция перемещается на границу следующего символа.

next

Ссылка на значение, которое будет установлено для следующей начальной позиции. Когда вызов возвращается, это может указывать на позицию первого байта за концом строки.

Возвращаемые значения

Строка, начинающаяся со смещения offset и заканчивающаяся границей кластера графемы по умолчанию, которая соответствует указанным size и type или false, если возникла ошибка.

Список изменений

Версия Описание
7.1.0 Добавлена поддержка отрицательных значений offset.

Примеры

Пример #1 Пример использования grapheme_extract()

<?php

$char_a_ring_nfd
= "a\xCC\x8A"; // 'LATIN SMALL LETTER A WITH RING ABOVE' (U+00E5) normalization form "D"
$char_o_diaeresis_nfd = "o\xCC\x88"; // 'LATIN SMALL LETTER O WITH DIAERESIS' (U+00F6) normalization form "D"

print urlencode(grapheme_extract( $char_a_ring_nfd . $char_o_diaeresis_nfd, 1, GRAPHEME_EXTR_COUNT, 2));

?>

Результат выполнения приведённого примера:

o%CC%88
Добавить

Примечания пользователей 3 notes

up
5
AJH
13 years ago
Here's how to use grapheme_extract() to loop across a UTF-8 string character by character.

<?php

$str
= "سabcक’…";
// if the previous line didn't come through, the string contained:
//U+0633,U+0061,U+0062,U+0063,U+0915,U+2019,U+2026

$n = 0;

for (
$start = 0, $next = 0, $maxbytes = strlen($str), $c = '';
$start < $maxbytes;
$c = grapheme_extract($str, 1, GRAPHEME_EXTR_MAXCHARS , ($start = $next), $next)
)
{
if (empty(
$c))
continue;
echo
"This utf8 character is " . strlen($c) . " bytes long and its first byte is " . ord($c[0]) . "\n";
$n++;
}
echo
"$n UTF-8 characters in a string of $maxbytes bytes!\n";
// Should print: 7 UTF8 characters in a string of 14 bytes!
?>
up
1
Philo
1 year ago
The other comments on this page were helpful for me.
However, consider using something better than empty($value) when checking the value returned by grapheme_extract since it could as well return something like "0" (which of course evaluates to false).
up
1
yevgen dot grytsay at gmail dot com
4 years ago
Looping through grapheme clusters:

<?php

// Example taken from Rust documentation: https://doc.rust-lang.org/book/ch08-02-strings.html#bytes-and-scalar-values-and-grapheme-clusters-oh-my
$str = "नमस्ते";
// Alternatively:
//$str = pack('C*', ...[224, 164, 168, 224, 164, 174, 224, 164, 184, 224, 165, 141, 224, 164, 164, 224, 165, 135]);
$next = 0;
$maxbytes = strlen($str);

var_dump($str);

while (
$next < $maxbytes) {
$char = grapheme_extract($str, 1, GRAPHEME_EXTR_COUNT, $next, $next);
if (empty(
$char)) {
continue;
}
echo
"{$char} - This utf8 character is " . strlen($char) . ' bytes long', PHP_EOL;
}

//string(18) "नमस्ते"
//न - This utf8 character is 3 bytes long
//म - This utf8 character is 3 bytes long
//स् - This utf8 character is 6 bytes long
//ते - This utf8 character is 6 bytes long
?>
To Top