将字符串转换为字符数组 - 多字节
Convert a String into an Array of Characters - multi-byte
假设在 2019 年,所有非 UNICODE 安全的解决方案都是错误的。将字符串转换为 PHP 中的 UNICODE 字符数组的最佳方法是什么?
显然这意味着使用大括号语法访问字节是错误的,以及使用 str_split
:
$arr = str_split($text);
来自示例输入,例如:
$string = '先éé€ ❤️';
我预计:
array(16) {
[0]=>
string(3) "先"
[1]=>
string(2) "é"
[2]=>
string(1) "e"
[3]=>
string(2) "́"
[4]=>
string(3) "€"
[5]=>
string(4) ""
[6]=>
string(4) ""
[7]=>
string(4) ""
[8]=>
string(3) ""
[9]=>
string(1) " "
[10]=>
string(4) ""
[11]=>
string(3) ""
[12]=>
string(3) "❤"
[13]=>
string(3) "️"
[14]=>
string(3) ""
[15]=>
string(4) ""
}
这对我有用,它将一个 unicode 字符串分解为一个字符数组:
//
// split at all position not after the start: ^
// and not before the end: $, with unicode modifier
// u (PCRE_UTF8).
//
$arr = preg_split("/(?<!^)(?!$)/u", $text);
例如:
<?php
//
$text = "堆栈溢出";
$arr = preg_split("/(?<!^)(?!$)/u", $text);
echo '<html lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
';
print_r($arr);
echo '</body>
</html>
';
?>
在浏览器中,它产生这个:
Array ( [0] => 堆 [1] => 栈 [2] => 溢 [3] => 出 )
只需传递带有 PREG_SPLIT_NO_EMPTY
标志的空模式。
否则,您可以使用 \X
(unicode 点)和 \K
(重新启动全字符串匹配)来编写模式。我将包括一个 mb_split()
调用和一个 preg_match_all()
完整性调用。
代码:(Demo)
$string='先秦兩漢';
var_export(preg_split('~~u', $string, 0, PREG_SPLIT_NO_EMPTY));
echo "\n---\n";
var_export(preg_split('~\X\K~u', $string, 0, PREG_SPLIT_NO_EMPTY));
echo "\n---\n";
var_export(preg_split('~\X\K(?!$)~u', $string));
echo "\n---\n";
var_export(mb_split('\X\K(?!$)', $string));
echo "\n---\n";
var_export(preg_match_all('~\X~u', $string, $out) ? $out[0] : []);
所有农产品::
array (
0 => '先',
1 => '秦',
2 => '兩',
3 => '漢',
)
来自 https://www.regular-expressions.info/unicode.html:
How to Match a Single Unicode Grapheme
Matching a single grapheme, whether it's encoded as a single code point, or as multiple code points using combining marks, is easy in Perl, PCRE, PHP, Boost, Ruby 2.0, Java 9, and the Just Great Software applications: simply use \X.
You can consider \X the Unicode version of the dot. There is one difference, though: \X always matches line break characters, whereas the dot does not match line break characters unless you enable the dot matches newline matching mode.
更新,DHarman 提醒我 mb_str_split()
现在可以从 PHP7.4.
获得
新函数的默认长度参数为1,所以本例可以省略长度参数。
https://wiki.php.net/rfc/mb_str_split
Dharman 的演示:https://3v4l.org/M85Fi/rfc#output
假设在 2019 年,所有非 UNICODE 安全的解决方案都是错误的。将字符串转换为 PHP 中的 UNICODE 字符数组的最佳方法是什么?
显然这意味着使用大括号语法访问字节是错误的,以及使用 str_split
:
$arr = str_split($text);
来自示例输入,例如:
$string = '先éé€ ❤️';
我预计:
array(16) {
[0]=>
string(3) "先"
[1]=>
string(2) "é"
[2]=>
string(1) "e"
[3]=>
string(2) "́"
[4]=>
string(3) "€"
[5]=>
string(4) ""
[6]=>
string(4) ""
[7]=>
string(4) ""
[8]=>
string(3) ""
[9]=>
string(1) " "
[10]=>
string(4) ""
[11]=>
string(3) ""
[12]=>
string(3) "❤"
[13]=>
string(3) "️"
[14]=>
string(3) ""
[15]=>
string(4) ""
}
这对我有用,它将一个 unicode 字符串分解为一个字符数组:
//
// split at all position not after the start: ^
// and not before the end: $, with unicode modifier
// u (PCRE_UTF8).
//
$arr = preg_split("/(?<!^)(?!$)/u", $text);
例如:
<?php
//
$text = "堆栈溢出";
$arr = preg_split("/(?<!^)(?!$)/u", $text);
echo '<html lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
';
print_r($arr);
echo '</body>
</html>
';
?>
在浏览器中,它产生这个:
Array ( [0] => 堆 [1] => 栈 [2] => 溢 [3] => 出 )
只需传递带有 PREG_SPLIT_NO_EMPTY
标志的空模式。
否则,您可以使用 \X
(unicode 点)和 \K
(重新启动全字符串匹配)来编写模式。我将包括一个 mb_split()
调用和一个 preg_match_all()
完整性调用。
代码:(Demo)
$string='先秦兩漢';
var_export(preg_split('~~u', $string, 0, PREG_SPLIT_NO_EMPTY));
echo "\n---\n";
var_export(preg_split('~\X\K~u', $string, 0, PREG_SPLIT_NO_EMPTY));
echo "\n---\n";
var_export(preg_split('~\X\K(?!$)~u', $string));
echo "\n---\n";
var_export(mb_split('\X\K(?!$)', $string));
echo "\n---\n";
var_export(preg_match_all('~\X~u', $string, $out) ? $out[0] : []);
所有农产品::
array (
0 => '先',
1 => '秦',
2 => '兩',
3 => '漢',
)
来自 https://www.regular-expressions.info/unicode.html:
How to Match a Single Unicode Grapheme
Matching a single grapheme, whether it's encoded as a single code point, or as multiple code points using combining marks, is easy in Perl, PCRE, PHP, Boost, Ruby 2.0, Java 9, and the Just Great Software applications: simply use \X.
You can consider \X the Unicode version of the dot. There is one difference, though: \X always matches line break characters, whereas the dot does not match line break characters unless you enable the dot matches newline matching mode.
更新,DHarman 提醒我 mb_str_split()
现在可以从 PHP7.4.
新函数的默认长度参数为1,所以本例可以省略长度参数。
https://wiki.php.net/rfc/mb_str_split
Dharman 的演示:https://3v4l.org/M85Fi/rfc#output