0

Catalyst アプリで Template Toolkit を使用します。UTF-8 を使用するように TT を構成しましたが、これまで問題はありませんでした。

ここで、文字列 var の substr() メソッドを呼び出します。残念ながら、 n文字ではなくnバイト後に文字列を分割します。n番目と(n+1)番目のバイトが unicode char を構築する場合、それは分割され、最初のバイトのみが substr() の結果の一部になります。

その動作を修正または回避する方法は?

[% string = "fööbär";

string.length; # prints 9

string.substr(0, 5); # prints "föö" (1 ascii + 2x 2 byte unicode)

string.substr(0, 4): # prints "fö?" (1 ascii, 1x 2 byte unicode, 1 unknown char)
%]

これまで、Unicode 文字に問題はありませんでした。データベースからのものでも、テンプレート内のテキストからのものでもありません。

編集:これはCatalyst::View::TT、Catalyst アプリでモジュールを構成する方法です。

__PACKAGE__->config(
#   DEBUG => DEBUG_ALL,
    DEFAULT_ENCODING => 'utf-8',
    INCLUDE_PATH => My::App->path_to( 'root', 'templates' ),
    TEMPLATE_EXTENSION => '.tt',
    WRAPPER => "wrapper/default.tt",
    render_die => 1,
);
4

3 に答える 3

3

MSWin32 テンプレート モジュールの Perl 1.12.2 で簡単なテストを行いました。これらすべての substr 操作を適切に処理できます。

これは私のテストコードです:

use Template;

# some useful options (see below for full list)
my $config = {
#    DEFAULT_ENCODING => 'utf-8',
    INCLUDE_PATH => 'd:/devel/perl',  # or list ref
    INTERPOLATE  => 1,               # expand "$var" in plain text
    EVAL_PERL    => 1,               # evaluate Perl code blocks
};

# create Template object
my $template = Template->new($config);

# define template variables for replacement
my $vars = {
    var1  => "abcdef"
};

# specify input filename, or file handle, text reference, etc.
my $input = 'ttmyfile.txt';

# process input template, substituting variables
print $template->process($input, $vars);

ttmyfile.txt

Var = [% var1 %]

[% string = "fööbär" -%]
[% string.length %]   # prints 6
[% string.substr(0, 5) %]  # prints "fööbä"
[% string.substr(0, 4) %]  # prints "fööb" 

出力:

Var = abcdef

6     # prints 6
fööbä  # prints "fööbä"
fööb  # prints "fööb" 
1

use utf8norがなくても、すべて正常に動作しますDEFAULT_ENCODING。ここで重要なこと:

  1. .ttテンプレートファイルがBOM --Byte Order Markで UTF8 としてエンコードされていることを確認してください。これは必須のタスクです。Template-Toolkit は、BOM に従って Unicode ファイルのエンコーディングを検出するためです。

    • Windows のメモ帳を使用して、BOM 付きのファイルを保存できます。File--> Save--> Encoding: "UTF-8" を実行してください。
    • VIM を使用して入力して作成しset fenc=utf8set bombファイルを保存すると、ファイルは BOM で始まります。
  2. NCODINGパラメータTemplate->new({NCODING => 'utf-8'});を「utf-8」に設定すると、Templateテンプレート ファイルが「utf-8」としてロードされます。

  3. スクリプトに含めることuse utf8をお勧めします。これにより、すべてのインライン文字列が正しく utf8 としてエンコードされます。

テンプレートに依存しているのでCatalyst::View::TT、それもうまくいくはずです! 頑張って~~~

于 2011-04-21T07:21:28.543 に答える
0

幸いなことに、答えは (Perl で) 非常に単純です。

use Encode qw{encode decode};

これが機能する方法は、Unicode 文字列を Perl 文字列にデコードし、substr() と length() を期待どおりに使用してから、それらを再度エンコードして出力することです。

そのヘッダーで:

# $unicodeString = 'fööbär';
my $perlString = decode('UTF-8', $unicodeString);
printf "%d\n", length($perlString);  # should be 6
printf "%s\n", substr($perlString, 0, 3);  # should be 'föö'
# whatever other processing you want here with $perlString . . .
# Then, you want to reencode that back to a proper UTF-8 string:
my $unicodeString = encode('UTF-8', $perlString);

それは役に立ちますか?

于 2011-04-21T06:37:12.097 に答える
0

The Wikipedia article on UTF-8 provides a table that shows how non-ASCII characters are encoded. That table illustrates the following simple rules for UTF-8:

  • If the highest bit of a byte is 0, then the byte denotes an ASCII character.

  • If the two highest bits of a byte are 11, then this is the start of a multi-byte character, and the number of consecutive 1 bits starting from the highest order bit indicates the total number of bytes in the multi-byte character. Thus, a byte whose bit representation is 110xxxxx is the start of a 2-byte character, 1110xxxx is the start of a 3-byte character, and 11110xxx is the start of a 4-byte character. (You can ignore the hypothetical 5-byte and 6-byte characters because Unicode is limited to being a 21-bit character set rather than a 32-bit character set.)

  • バイトの上位 2 ビットが 10 の場合、このバイトはマルチバイト文字の一部です (ただし、その文字の最初のバイトではありません)。

string.lengthその情報は、string.substring()バイトではなく文字に関して機能する独自のユーティリティ関数を作成するのに十分なはずです。

更新:質問では、使用されているプログラミング言語が指定されておらず、「テンプレート ツールキット」が Perl の使用を暗示していることを認識していませんでした。これに気付いた後、Google 検索を行ったところuse utf8、ソース コードにディレクティブを追加する必要があることが問題の原因である可能性が高いことがわかりました。これについての議論はここにあります

于 2011-04-14T10:21:02.140 に答える