我写了一个小的 perl 函数,它接受一个字符串并检查它的长度,没有空格。基本代码如下所示:
sub foo
{
use utf8;
my @wordsArray = split(/ /, $_[0]));
my $result = length(join('', @wordsArray));
return $result;
}
当我为这个函数提供一个包含特殊字符(如希伯来字母)的字符串时,它似乎工作得很好。当我使用来自 MySql 列的值,字符集为 utf8mb4 时,问题就开始了:在这种情况下,计算的值高于上一个示例中的值。
我可以猜到为什么会发生这种行为:特殊字符以 4 字节的方式写入表中,因此每个字母在 utf8 编码中计算为两个字符。
有谁知道如何解决上述问题,以便我从来自定义为 utf8mb4 的 DB 表的字符串中获得正确数量的字符?
编辑:
有关上述代码的更多信息:
用作函数参数的 DB 列是 VARCHAR(1000) 类型,排序规则为 utf8mb4_unicode_ci。我通过如下配置的 MySql 连接获取行:
$mySql = DBI->connect(
"DBI:mysql:$db_info{'database'}:$db_info{'hostname'};mysql_multi_statements=1;",
"$db_info{'user'}",
"$db_info{'password'}",
{'RaiseError' => 1,'AutoCommit' => 0});
...
$mySql->do("set names utf8mb4");
示例数据值为“שלום עולם”(在希伯来语中意为“Hello World”)。
1) 调用时foo($request->{VALUE});
(其中 VALUE 为 DB 中的列数据),结果为 16(其中每个希伯来字符计为两个字符,忽略它们之间的一个空格)。在这种情况下,Dumper 是:
$VAR1 = "\327\251\327\234\327\225\327\235 \327\242\327\225\327\234\327\235";
2)打电话时foo("שלום עולם");
:
声明时
use utf8;
,结果为 8(因为此字符串中有 8 个可见字符)。在这种情况下,Dumper (Useqq=1) 是:$VAR1 = "\x{5e9}\x{5dc}\x{5d5}\x{5dd}\x{5e2}\x{5d5}\x{5dc}\x{5dd}";
不声明 `use utf8;' 时,结果为 16,类似于从 DB 发送值的情况:
$VAR1 = "\327\251\327\234\327\225\327\235\327\242\327\225\327\234\327\235";
看起来我需要在开始使用它之前找到一种将接收到的值转换为 UTF8 的方法。