在Perl中,如何用简单的ASCII字符替换UTF8字符,例如\x91、\x{2018}、\x{2013}、\x{2014}?
我正在处理各种文章,我遇到的问题是,不同的作者使用不同的字符作为标点符号 例如,我目前使用的几个文档具有以下字符:在Perl中,如何用简单的ASCII字符替换UTF8字符,例如\x91、\x{2018}、\x{2013}、\x{2014}?,perl,encoding,character-encoding,ascii,non-ascii-characters,Perl,Encoding,Character Encoding,Ascii,Non Ascii Characters,我正在处理各种文章,我遇到的问题是,不同的作者使用不同的字符作为标点符号 例如,我目前使用的几个文档具有以下字符: \x91 \x92 \x{2018} \x{2019} 所有这些字符都代表一个简单的引号 我想做的是简化文章,使它们具有相同的格式样式 有人知道将这些字符和类似字符(如双引号、破折号等)转换为简单ASCII字符的模块或方法吗 我目前正在做以下工作: sub fix_chars_in_document { my $document = shift; $documen
\x91
\x92
\x{2018}
\x{2019}
所有这些字符都代表一个简单的引号
我想做的是简化文章,使它们具有相同的格式样式
有人知道将这些字符和类似字符(如双引号、破折号等)转换为简单ASCII字符的模块或方法吗
我目前正在做以下工作:
sub fix_chars_in_document {
my $document = shift;
$document =~ s/\xa0/ /g;
$document =~ s/\x91/'/g;
$document =~ s/\x92/'/g;
$document =~ s/\x93/"/g;
$document =~ s/\x94/"/g;
$document =~ s/\x97/-/g;
$document =~ s/\xab/"/g;
$document =~ s/\xa9//g;
$document =~ s/\xae//g;
$document =~ s/\x{2018}/'/g;
$document =~ s/\x{2019}/'/g;
$document =~ s/\x{201C}/"/g;
$document =~ s/\x{201D}/"/g;
$document =~ s/\x{2022}//g;
$document =~ s/\x{2013}/-/g;
$document =~ s/\x{2014}/-/g;
$document =~ s/\x{2122}//g;
return $document ;
}
但这非常困难,因为我必须手动查找字符并替换它们。首先,您的解决方案将受益于哈希
my %asciify = (
chr(0x00A0) => ' ',
chr(0x0091) => "'",
chr(0x0092) => "'",
chr(0x0093) => '"',
chr(0x0094) => '"',
chr(0x0097) => '-',
chr(0x00AB) => '"',
chr(0x00A9) => '/',
chr(0x00AE) => '/',
chr(0x2018) => "'",
chr(0x2019) => "'",
chr(0x201C) => '"',
chr(0x201D) => '"',
chr(0x2022) => '/',
chr(0x2013) => '-',
chr(0x2014) => '-',
chr(0x2122) => '/',
);
my $pat = join '', map quotemeta, keys %asciify;
my $re = qr/[$pat]/;
sub fix_chars {
my ($s) = @_;
$s =~ s/($re)/$asciifi{$1}/g;
return $s;
}
也就是说,你想要
仅标点符号:
use Text::Unidecode qw( unidecode );
s/(\p{Punct}+)/ unidecode($1) /eg;
首先,您的解决方案将受益于散列
my %asciify = (
chr(0x00A0) => ' ',
chr(0x0091) => "'",
chr(0x0092) => "'",
chr(0x0093) => '"',
chr(0x0094) => '"',
chr(0x0097) => '-',
chr(0x00AB) => '"',
chr(0x00A9) => '/',
chr(0x00AE) => '/',
chr(0x2018) => "'",
chr(0x2019) => "'",
chr(0x201C) => '"',
chr(0x201D) => '"',
chr(0x2022) => '/',
chr(0x2013) => '-',
chr(0x2014) => '-',
chr(0x2122) => '/',
);
my $pat = join '', map quotemeta, keys %asciify;
my $re = qr/[$pat]/;
sub fix_chars {
my ($s) = @_;
$s =~ s/($re)/$asciifi{$1}/g;
return $s;
}
也就是说,你想要
仅标点符号:
use Text::Unidecode qw( unidecode );
s/(\p{Punct}+)/ unidecode($1) /eg;
当然,这是假设您实际上仅限于ASCII。我希望你不要只是采取用洗澡水把孩子扔掉的方法来解决问题。谢谢你的建议。我尝试了Text::Unidecode,但它也会将像“a”这样的字符(上面有东西)转换为简单的a等。我只需要将破折号、引号和其他简单的标点符号转换为ascii。当然,这是假设您确实只限于ascii。我希望你不要只是采取用洗澡水把孩子扔掉的方法来解决问题。谢谢你的建议。我试过Text::Unidecode,但它也会将像“a”这样的字符(上面有东西)转换为简单的a等。我只需要将破折号、引号和其他简单的标点字符转换为ascii。也许可以看看CPAN上的Text::Unidecode。@DaveCross我试过了,但它会影响所有字符,而不仅仅是破折号、点,引号。也许看看CPAN上的Text::Unidecode。@DaveCross我刚试过,但它会影响所有字符,而不仅仅是破折号、点和引号。