perl 确定亚洲/日语字符终端的宽度?

kqlmhetl  于 2023-03-13  发布在  Perl
关注(0)|答案(1)|浏览(121)

在我的航站楼里,这两条线同样宽:

ヌー平行
parallel
æøåüäöûß

我已经设法让Perl为最后两行给予长度8,但它报告第一行的长度为4。有没有办法确定的宽度是Ø的两倍?

vmdwslir

vmdwslir1#

你可以使用Text::CharWidthmbswidth,它使用的是POSIX的wcwidth

use v5.14;
use warnings;

use utf8;
use open ':std', ':encoding(UTF-8)';

use Encode             qw( encode_utf8 );
use Text::CharWidth    qw( mbswidth );
use Unicode::Normalize qw( NFC NFD );

my @tests = (
   [ "ASCII",     "parallel",      8 ],
   [ "NFC",       NFC("æøåüäöûß"), 8 ],
   [ "NFD",       NFD("æøåüäöûß"), 8 ],
   [ "EastAsian", "ヌー平行",      8 ],
);

for ( @tests ) {
   my ( $name, $s, $expect ) = @$_;
   my $length = length( $s );
   my $got = mbswidth( encode_utf8( $s ) );
   printf "%-9s length=%2d expect=%d got=%d\n", 
      $name, $length, $expect, $got;
}
ASCII     length= 8 expect=8 got=8
NFC       length= 8 expect=8 got=8
NFD       length=13 expect=8 got=8
EastAsian length= 4 expect=8 got=8

注意,mbswidth需要一个使用语言环境编码的字符串,在上面的程序中,我假设有两处是UTF-8。
如果你想知道一个字符串根据Unicode应该占多少列,Unicode Standard Annex #11就可以解决这个问题。注意,答案可能取决于它是否在东亚环境中。例如,U+03 A6 GREEK CAPITAL LETTER PHI(“Φ”)在东亚环境中占两列,而在其他环境中只占一列。

相关问题