如何获得可以在\ N {}中使用的所有值来生成特定的代码点?

时间:2017-01-19 15:44:02

标签: perl unicode

在为this question执行调试时,我问自己:如何找到\N{}中给定Unicode代码点可以使用的所有值?

例如,我想知道U + 03B1(GREEK SMALL LETTER ALPHA)的所有别名。我怎么知道\N{greek:alpha}可以用于此?

1 个答案:

答案 0 :(得分:3)

没有一个列表可以用来检查这些列表。

根据\N{}的{​​{3}},以下内容可以解决问题:

use List::Util   qw( max );
use Unicode::UCD qw( charscripts charinfo charprop );

my $re_scripts = join '|', map { quotemeta uc s/_/ /gr } keys %{ charscripts() };
my $re_letter = qr/^($re_scripts) (?:(CAPITAL|SMALL) )?LETTER (\S.*)/;

{
   @ARGV == 1
     or die("usage\n");

   my $ucp = hex( $ARGV[0] =~ s/^(?:U\+|0x)//r );

   my @names;
   push @names, [ "", sprintf('U+%X', $ucp) ];

   if ( my $charinfo = charinfo($ucp) ) {
      my $name = $charinfo->{name};
      push @names, [ ":full", $name ] if length($name) && $name ne '<control>';

      for my $alias (map s/:.*//sr, split /,/, charprop($ucp, 'Name_Alias')) {
         push @names, [ ":full", $alias ];
      }

      if ( my ($script_name, $type, $short_char_name) = $name =~ $re_letter ) {
         my $uc = ( $type // 'CAPITAL' ) eq 'CAPITAL';
         my $lc = ( $type // 'SMALL'   ) eq 'SMALL';
         push @names, [ ":short", join(":", $script_name, uc($short_char_name)) ] if $uc;
         push @names, [ ":short", join(":", $script_name, lc($short_char_name)) ] if $lc;
         push @names, [ $script_name, uc($short_char_name) ] if $uc;
         push @names, [ $script_name, lc($short_char_name) ] if $lc;
      }
   }

   my $longuest = max map length($_->[0]), @names;
   say sprintf("use charnames qw( %-*s ); \"\\N{%s}\"", $longuest, @$_) for @names;
}

例如,

$ ./script.pl U+03B1
use charnames qw(        ); "\N{U+3B1}"
use charnames qw( :full  ); "\N{GREEK SMALL LETTER ALPHA}"
use charnames qw( :short ); "\N{GREEK:alpha}"
use charnames qw( GREEK  ); "\N{alpha}"

$ ./script.pl U+0391
use charnames qw(        ); "\N{U+391}"
use charnames qw( :full  ); "\N{GREEK CAPITAL LETTER ALPHA}"
use charnames qw( :short ); "\N{GREEK:ALPHA}"
use charnames qw( GREEK  ); "\N{ALPHA}"

$ perl a.pl 1C00
use charnames qw(        ); "\N{U+1C00}"
use charnames qw( :full  ); "\N{LEPCHA LETTER KA}"
use charnames qw( :short ); "\N{LEPCHA:KA}"
use charnames qw( :short ); "\N{LEPCHA:ka}"
use charnames qw( LEPCHA ); "\N{KA}"
use charnames qw( LEPCHA ); "\N{ka}"

$ ./script.pl 20
use charnames qw(       ); "\N{U+20}"
use charnames qw( :full ); "\N{SPACE}"
use charnames qw( :full ); "\N{SP}"

注意:

  • charnames.pm中的脚本名称导入参数不区分大小写。
  • 输出中use charnames qw( );的实例(即没有参数的指令加载charnames.pm)实际上是不必要的。
  • 从Perl 5.16开始,如果在遇到use charnames qw( :full :short );之前加载了\N{},则使用U+隐式加载charnames.pm。
  • 未列出有效的自定义别名。 (从技术上讲,除非您修改脚本,否则没有任何内容。)
  • 必须提供与输出完全相同的名称,但以下情况除外:
    • U+后面的数字不区分大小写。
    • :short后面的数字可能有前导零。
    • :short名称中的脚本名称不区分大小写。
    • use charnames qw( :loose );和脚本字符名称中的大写字符名称不区分大小写,但必须至少包含一个大写字符。
    • 使用 DataContext db = new DataContext(); public SupliersForm() { InitializeComponent(); supliersDG.DataSource = db.Supliers.Local.ToBindingList(); db.Supliers.Load(); } private void SaveBtn_Click(object sender, EventArgs e) { supliersDG.EndEdit(); db.SaveChanges(); } 可以进一步更改显示的字符串。