PHP Conference Japan 2024

grapheme_extract

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

grapheme_extract从文本缓冲区提取默认字素簇序列的函数,该缓冲区必须以 UTF-8 编码

描述

过程式风格

grapheme_extract(
    字符串 $haystack,
    整数 $size,
    整数 $type = GRAPHEME_EXTR_COUNT,
    整数 $offset = 0,
    整数 &$next = null
): 字符串|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 位置开始,并在符合指定 sizetype 的默认字素簇边界结束的字符串,或者在失败时返回 false

变更日志

版本 描述
7.1.0 添加了对负 offset 的支持。

示例

示例 #1 grapheme_extract() 示例

<?php

$char_a_ring_nfd
= "a\xCC\x8A"; // '带环的拉丁小写字母 A' (U+00E5) 规范化形式 "D"
$char_o_diaeresis_nfd = "o\xCC\x88"; // '带分音符的拉丁小写字母 O' (U+00F6) 规范化形式 "D"

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

?>

以上示例将输出

o%CC%88

参见

添加注释

用户贡献的注释 3 条注释

AJH
13 年前
以下是如何使用 grapheme_extract() 逐个字符循环遍历 UTF-8 字符串。

<?php

$str
= "سabcक’…";
// 如果上一行没有显示,字符串包含:
//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
"这个 utf8 字符是 " . strlen($c) . " 字节长,它的第一个字节是 " . ord($c[0]) . "\n";
$n++;
}
echo
"$n 个 UTF-8 字符在一个包含 $maxbytes 个字节的字符串中!\n";
// 应该打印:7 个 UTF-8 字符在一个包含 14 个字节的字符串中!
?>
Philo
1 年前
此页面上的其他评论对我有帮助。
但是,在检查 grapheme_extract 返回的值时,请考虑使用比 empty($value) 更好的方法,因为它也可能返回类似“0”的值(当然这会评估为 false)。
yevgen dot grytsay at gmail dot com
4 年前
遍历字素簇

<?php

// 示例取自 Rust 文档:https://doc.rust-lang.net.cn/book/ch08-02-strings.html#bytes-and-scalar-values-and-grapheme-clusters-oh-my
$str = "नमस्ते";
// 或者:
//$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} - 此 UTF8 字符长度为 " . strlen($char) . ' 字节', PHP_EOL;
}

//string(18) "नमस्ते"
//न - 此 UTF8 字符长度为 3 字节
//म - 此 UTF8 字符长度为 3 字节
//स् - 此 UTF8 字符长度为 6 字节
//ते - 此 UTF8 字符长度为 6 字节
?>
To Top