Mysql Perl字符串操作和utf8/unicode

Mysql Perl字符串操作和utf8/unicode,mysql,perl,utf-8,Mysql,Perl,Utf 8,在人们开始将维基百科中包含utf8字符的文本字符串复制粘贴到输入字段之前,我一直以为这是一个简单的web表单。我的perl CGI脚本打开MySQL数据库连接并设置 $DBH->{mysql_enable_utf8} = 1; $DBH->do("set names 'utf8';"); 我正在尝试使用Encode模块对目标输入值进行解码、使用和编码,但这并不像我预期的那样有效。网页设置为utf8字符集 在本例中,我的目标字符串是Baden-Württemberg[从列出德国城镇名

在人们开始将维基百科中包含utf8字符的文本字符串复制粘贴到输入字段之前,我一直以为这是一个简单的web表单。我的perl CGI脚本打开MySQL数据库连接并设置

$DBH->{mysql_enable_utf8} = 1;
$DBH->do("set names 'utf8';");
我正在尝试使用
Encode
模块对目标输入值进行解码、使用和编码,但这并不像我预期的那样有效。网页设置为utf8字符集

在本例中,我的目标字符串是
Baden-Württemberg
[从列出德国城镇名称的维基百科页面复制]。发送请求时,我可以看到目标字符串为:
Baden-W%C3%BCrttemberg
。不过,这并没有很好地贯穿我的CGI脚本

我有以下示例脚本:

#!/usr/local/bin/perl -w

use strict;
select(STDOUT);
$|++;

use feature 'unicode_strings';
use Encode;
use utf8;

binmode STDOUT, ":utf8";

my $thing = "Baden-Württemberg";
print STDOUT "$thing\n";

my $decodedThing = decode_utf8($thing);
print STDOUT encode_utf8($decodedThing) . "\n";
$thing
的值在'-W'后面有一个带umlaut的'u'

当我运行脚本时,我得到:

# ./test.pl
Malformed UTF-8 character (unexpected non-continuation byte 0x72, immediately after start byte 0xfc) at ./test.pl line 13.
Baden-Wrttemberg
Baden-Wrttemberg

u-umlaut去了哪里?如何取回它?

%C3%BC
urlencode
。对于MySQL,您不需要这样做,尽管在构建URL时可能需要这样做

ü
当您将utf8字节存储为拉丁文1列时发生。请提供
SHOW CREATE TABLE

我认为你不需要对任何东西进行编码/解码

./test.pl第13行的UTF-8字符格式错误(意外的非连续字节0x72,紧跟在起始字节0xfc之后)

表示您有十六进制
FC
(这是
u
的拉丁十六进制),但您将字符串视为utf8(“意外…””)
72
是后面的
r

底线:在整个处理过程中(手头的字节、集合名称、字符集等),您都不是utf8。

问题1 您告诉Perl您的源文件是使用UTF-8编码的

use utf8;
事实并非如此
u
由文件中的
FC
表示,而不是
c3bc
。(这就是您收到“格式错误”消息的原因。)修复源文件的编码

mv file.pl file.pl~ && piconv -f iso-8859-1 -t UTF-8 file.pl~ >file.pl
问题2 以下是毫无意义的:

my $decodedThing = decode_utf8($thing);
print STDOUT encode_utf8($decodedThing);
由于
使用utf8
$thing
将被解码

问题3 以下是毫无意义的:

my $decodedThing = decode_utf8($thing);
print STDOUT encode_utf8($decodedThing);
您要求Perl自动编码发送到STDOUT的每个数据,所以您是双重编码

固定的
原来Rick James的最后一行
底线:在整个处理过程中(手头的字节、集合名、字符集等),您不是utf8。
是关键。我确实需要Encode模块,但实际上只需要DB insert语句,la:

if (!($sth->execute(encode('UTF-8', $_))) && $DBI::err != 1062) {
    die "DB execute failed :" . $DBI::err . ": " . $DBI::errstr;
}

感谢大家

创建表
nametokes
id
int(11)无符号非空自动增量,
token
varchar(128)非空,主键(
id
),唯一键
token
))引擎=InnoDB自动增量=124默认字符集=utf8