У меня есть HTML-форма, которая отправляет данные на страницу .cgi. Вот HTML:
<HTML>
<BODY BGCOLOR="#FFFFFF">
<FORM METHOD="post" ACTION="test.cgi">
<B>Write to me below:</B><P>
<TEXTAREA NAME="feedback" ROWS=10 COLS=50></TEXTAREA><P>
<CENTER>
<INPUT TYPE=submit VALUE="SEND">
<INPUT TYPE=reset VALUE="CLEAR">
</CENTER>
</FORM>
</BODY>
</HTML>
Вот скрипт perl для test.cgi:
#!/usr/bin/perl
use utf8;
use encoding('utf8');
require Encode;
require CGI;
# The following accepts the data from the form and puts it in %FORM
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
# The following generates the html for the page
print "Content-type: text/html\n\n";
print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>Thank You!</TITLE>\n";
print "</HEAD>\n";
print "<BODY BGCOLOR=#FFFFCC TEXT=#000000>\n";
print "<H1>Thank You!</H1>\n";
print "<P>\n";
print "<H3>Your feedback is greatly appreciated.</h3><BR>\n";
print "<P>\n<P>\n";
print "The user wrote:\n\n";
print "<P>\n";
# This is print statement A
print "$FORM{'feedback'}<br>\n";
$FORM{'feedback'}=~s/(\w)/ $1/g;
# This is print statement B
print "$FORM{'feedback'}\n";
print "</BODY>\n";
print "</HTML>\n";
exit(0);
}
Это все работает так, как должно, если пользователь вводит текст на английском языке. Тем не менее, это в конечном итоге будет использоваться в продукте, где пользователь будет вводить текст на китайском языке. Итак, вот пример проблемы. Если пользователь вводит в форму «中文», то «Печать выписки А» печатает «中文». Однако оператор Print B (который печатает значение $ после выполнения регулярного выражения) печатает "& # 2 0 0 1 3; & # 2 5 9 9 1;". Однако я хочу, чтобы он напечатал «中 文». Если вы хотите это увидеть, перейдите на http://thedeandp.com/chinese/input.html и попробуйте сами.
Итак, в основном я понял, что когда perl читает в форме, он просто обрабатывает каждый байт как символ, поэтому регулярное выражение добавляет пробел между каждым байтом. Китайские иероглифы используют юникод, поэтому это несколько байтов на символ. Это означает, что регулярное выражение разбивает юникод с пробелом между байтами, и это то, что производит вывод, видимый в операторе Print B. Я пробовал такие методы, как $ value = Encode :: decode_utf8 ($ value), чтобы обработать perl это как Unicode, но пока ничего не работает.