Perl 使用日语(宽)字体的Excel

Perl 使用日语(宽)字体的Excel,perl,unicode,Perl,Unicode,我正在分析一个Excel文件,其中一些单元格中有日语。通过使用电子表格::ParseExcel(版本0.15)(我知道它比当前版本旧),一些单元格包含以下字符: <設定B-1コース> 现列为: 打印转储程序$oWkc->{U值} $VAR1=“\x{ff1c}\x{8a2d}\x{5b9a}B-\x{ff11}\x{30b3}\x{30fc}\x{30b9}\x{ff1e}” 及 打印$oWkc->{Val}。“\n” [-0 $VAR1=“\x{ff1c}\x{8a2d}\x{5b9a}B-\

我正在分析一个Excel文件,其中一些单元格中有日语。通过使用电子表格::ParseExcel(版本0.15)(我知道它比当前版本旧),一些单元格包含以下字符:

<設定B-1コース>

现列为:

打印转储程序$oWkc->{U值}

$VAR1=“\x{ff1c}\x{8a2d}\x{5b9a}B-\x{ff11}\x{30b3}\x{30fc}\x{30b9}\x{ff1e}”

打印$oWkc->{Val}。“\n”

[-0

$VAR1=“\x{ff1c}\x{8a2d}\x{5b9a}B-\x{ff13}\x{30b3}\x{30fc}\x{30b9}\x{ff1e}”

[-0

如果我想在实际的foramat中打印这些值,我将标准输出文件句柄设置为“:utf8”,并将终端显示utf-8编码(否则我将得到一些“宽字符”警告)。在这里,我必须用B选择单元格-1 或者B-2,但我不确定应该在我的脚本中设置什么,以便这些字符可以被视为我能够在标准输出上看到的字符

目前,我正在使用正则表达式将这些宽字符转换为相应的ASCII值。例如,如果我想匹配存储为“B-\x{ff11}”的B-1,我将

$oWkc->{_Value} =~ /([AB]-)(\x{ff11}|\x{ff12}|\x{ff13}/
my $lookup = $1.$2;
$lookup =~ s/\x{ff11}/1/;
$lookup =~ s/\x{ff12}/2/;
$lookup =~ s/\x{ff13}/3/;
作为参考,B-1、A-2等这些值来自其他来源,目前的范围为A | B-[1-3]

处理这些宽字符的标准方法是什么?我不能使用编码/解码等。有人能给我一些指导吗

目前,虽然我能够使用regex完成工作…

但我没有验证它(我从2001年3月起不打算安装模块),该模块显然已经解码为Perl本机字符串,因此您不需要做太多工作。简单的方法工作得很好,不需要通过这些替换使事情过于复杂

use utf8;
my $val = '<設定B-1コース>';

# does it match A or B, followed by a dash, followed by a fullwidth 1,2 or 3?
$val =~ /(?:A|B)-[123]/;  # returns true/1
虽然我没有验证它(我不打算从2001年3月开始安装一个模块),但该模块显然已经解码为Perl本机字符串,因此您不需要做太多工作。简单的方法工作得很好,不需要通过这些替换将事情过度复杂化

use utf8;
my $val = '<設定B-1コース>';

# does it match A or B, followed by a dash, followed by a fullwidth 1,2 or 3?
$val =~ /(?:A|B)-[123]/;  # returns true/1

要处理中的多字节字符,您应该更新到最新版本并使用FmtJapan格式化程序。最近的版本中出现了一些关于日语格式化的错误修复

以下是一个例子:

#!/usr/bin/perl


use warnings;
use strict;
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::FmtJapan;

my $filename  = 'Test2000J.xls';
my $parser    = Spreadsheet::ParseExcel->new();
my $formatter = Spreadsheet::ParseExcel::FmtJapan->new();
my $workbook  = $parser->parse($filename, $formatter);

if ( !defined $workbook ) {
    die "Parsing error: ", $parser->error(), ".\n";
}

# Set your output encoding.
binmode STDOUT, ':encoding(cp932)';
# Or maybe this:
#binmode STDOUT, ':utf8';


for my $worksheet ( $workbook->worksheets() ) {

    print "Worksheet name: ", $worksheet->get_name(), "\n\n";

    my ( $row_min, $row_max ) = $worksheet->row_range();
    my ( $col_min, $col_max ) = $worksheet->col_range();

    for my $row ( $row_min .. $row_max ) {
        for my $col ( $col_min .. $col_max ) {

            my $cell = $worksheet->get_cell( $row, $col );
            next unless $cell;

            print "    Row, Col    = ($row, $col)\n";
            print "    Value       = ", $cell->value(),       "\n";
            print "    Unformatted = ", $cell->unformatted(), "\n";
            print "\n";
        }
    }
}

要处理中的多字节字符,您应该更新到最新版本并使用FmtJapan格式化程序。最近的版本中出现了一些关于日语格式化的错误修复

以下是一个例子:

#!/usr/bin/perl


use warnings;
use strict;
use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::FmtJapan;

my $filename  = 'Test2000J.xls';
my $parser    = Spreadsheet::ParseExcel->new();
my $formatter = Spreadsheet::ParseExcel::FmtJapan->new();
my $workbook  = $parser->parse($filename, $formatter);

if ( !defined $workbook ) {
    die "Parsing error: ", $parser->error(), ".\n";
}

# Set your output encoding.
binmode STDOUT, ':encoding(cp932)';
# Or maybe this:
#binmode STDOUT, ':utf8';


for my $worksheet ( $workbook->worksheets() ) {

    print "Worksheet name: ", $worksheet->get_name(), "\n\n";

    my ( $row_min, $row_max ) = $worksheet->row_range();
    my ( $col_min, $col_max ) = $worksheet->col_range();

    for my $row ( $row_min .. $row_max ) {
        for my $col ( $col_min .. $col_max ) {

            my $cell = $worksheet->get_cell( $row, $col );
            next unless $cell;

            print "    Row, Col    = ($row, $col)\n";
            print "    Value       = ", $cell->value(),       "\n";
            print "    Unformatted = ", $cell->unformatted(), "\n";
            print "\n";
        }
    }
}

忘了提到我用CPAN最新版本的模块试过了,并提供了我自己的格式化程序,如下所述:电子表格::ParseExcel::FmtJapanForget要提到的是,我用CPAN最新版本的模块试过了,并提供了我自己的格式化程序,如下所述:电子表格::ParseExcel::FMTjapant感谢您的回复,但我的$val='<設定B-1コース>'; 在perl中的任何位置都不显示,它是从excel中打开的工作表复制和粘贴的。相反,存储在perl对象中的值存储为宽字符代码,如我的注释1中所示,或那些[-0'伪值。目前,我正在寻找某种方法,以获取ascii范围内显示的所有值,以宽字符代码转换为相应的ascii,以便我可以使用正则表达式匹配并获取这些行,以便在我的应用程序中进行进一步处理。我的
$val
转储到与您的应用程序完全相同的表示形式在问题中写入。您称之为宽字符代码,但它实际上只是本地Perl字符串。-要用ASCII数字替换全宽数字,只需使用utf8;$val=~tr[0-9][0-9];。在这种情况下,它应该打印$oWkc->{u Value}=~tr[0-9][0-9];打印$oWkc->{u Value}.\n“if($oWkc->{u Value}=~/B-1/);当有含有B-1的单元格时,但我没有得到任何东西。你是缺少复制和粘贴的受害者。我写了
tr[0-9][0-9];
,而不是
tr[0-9][0-9];
。它们是不同的,只有第一个按预期工作。感谢您的回复,但我的$val='<設定B-1コース>'; 在perl中的任何位置都不显示,它是从excel中打开的工作表复制和粘贴的。相反,存储在perl对象中的值存储为宽字符代码,如我的注释1中所示,或那些[-0'伪值。目前,我正在寻找某种方法,以获取ascii范围内显示的所有值,以宽字符代码转换为相应的ascii,以便我可以使用正则表达式匹配并获取这些行,以便在我的应用程序中进行进一步处理。我的
$val
转储到与您的应用程序完全相同的表示形式在问题中写入。您称之为宽字符代码,但它实际上只是本地Perl字符串。-要用ASCII数字替换全宽数字,只需使用utf8;$val=~tr[0-9][0-9];。在这种情况下,它应该打印$oWkc->{u Value}=~tr[0-9][0-9];打印$oWkc->{u Value}.\n“if($oWkc->{u Value}=~/B-1/);当有含有B-1的单元格时,但我没有得到任何东西。你是缺少复制和粘贴的受害者。我写了
tr[0-9][0-9];
,而不是
tr[0-9][0-9];
。它们是不同的,只有第一个按预期工作。