我无法隔离这个问题。我有一个 HTML 表单文本输入,它通过 Perl ASP 保存到 SQLite 数据库中。如果我只是保存表单数据®
或者使用以下方法替换字符:
$registered = chr(174);
$DESCRIPTION =~ s/$registered/R/g;
检索数据时,我得到一个额外的字符,®
或者ÂR
如果我用上面的代码替换商标,再次保存它,我又得到î
, ÃÂî
。是ÃÂ
从哪里来的??
我无法隔离这个问题。我有一个 HTML 表单文本输入,它通过 Perl ASP 保存到 SQLite 数据库中。如果我只是保存表单数据®
或者使用以下方法替换字符:
$registered = chr(174);
$DESCRIPTION =~ s/$registered/R/g;
检索数据时,我得到一个额外的字符,®
或者ÂR
如果我用上面的代码替换商标,再次保存它,我又得到î
, ÃÂî
。是ÃÂ
从哪里来的??
在连接中将 sqlite_unicode 属性设置为 1:
$dbh = DBI::connect( "dbi:SQLite:dbname=foo", "", "", { sqlite_unicode => 1 } );
之后,在设置一些二进制数据列时,您可能需要将它们显式表示为二进制:
$sth->bind_param(1, $binary_data, SQL_BLOB);
当您使用它时,该字符串可能采用 UTF-8(Perl 的字符编码标准)。UTF-8 中的注册商标符号是两个字节,您只需替换其中一个。 有关该字符的编码,请在此处查看更多信息。
如果您想用正则表达式替换符号,请使用除chr()
匹配适当字符之外的方法。你应该能够做到这一点:
s/\x{c2ae}/R/g;
\x
匹配以十六进制给出的 UTF-8 字符。我从上面链接的页面中获得了十六进制编码。
有关更多信息,请参阅perlre中的“转义序列” 。
另请参阅Encode
核心模块以获取有关 Perl 如何处理字符编码的更多信息。
也许这次巡演会让您了解您正在打什么?我猜chr2
是你的问题所在。
use strictures;
use utf8;
use DBI;
my $dbh = DBI->connect("dbi:SQLite::memory:", undef, undef,
{ sqlite_unicode => 1,
PrintError => 1 } );
$dbh->do(<<"");
CREATE TABLE moo (
name TEXT
,string TEXT )
my $insert = $dbh->prepare("INSERT INTO moo VALUES ( ?, ? )");
my %reg = ( raw => "®", # note "use utf8;"
"chr" => chr(174) );
while ( my ( $name, $reg ) = each %reg )
{
$insert->execute($name, $reg);
}
# And a couple without placeholders (which we all know is EVIL, right?)
$dbh->do(<<"");
INSERT INTO moo VALUES( "raw2", "®" )
my $reg = chr(174);
$dbh->do(<<"");
INSERT INTO moo VALUES( "chr2", "$reg" )
my $sth = $dbh->prepare("SELECT * FROM moo");
$sth->execute;
binmode STDOUT, ":encoding(UTF-8)";
while ( my $row = $sth->fetchrow_hashref )
{
print $row->{name}, " -> ", $row->{string}, $/;
}
__DATA__
chr -> ®
raw -> ®
raw2 -> ®
"\x{00ae}" does not map to utf8.
chr2 -> \xAE
在查看了字符串中的实际字符后:
foreach (split //, $DESCRIPTION) {
$hold = ord($_);
%>chr(<%= $hold %>)<br><%
}
我发现®
来自 html 表单的文本输入被视为/接收为 chr(194).chr(174)。所以:
$registered = chr(194).chr(174);
$DESCRIPTION =~ s/$registered/®/g;
允许我毫无问题地将其保存到数据库中...