Где я могу найти массив (не) назначенных кодовых точек Unicode для определенного блока? - PullRequest
3 голосов
/ 22 мая 2010

В данный момент я пишу эти массивы вручную.

Например, в блоке Разные математические символы-A есть запись в хэше, например:

my %symbols = (
    ...
    miscellaneous_mathematical_symbols_a => [(0x27C0..0x27CA), 0x27CC,
        (0x27D0..0x27EF)],
    ...
)

Более простой, "непрерывный" массив

miscellaneous_mathematical_symbols_a => [0x27C0..0x27EF]

не работает, потому что в блоках Юникода есть отверстия. Например, в 0x27CB ничего нет. Взгляните на кодовую таблицу [PDF].

Написание этих массивов вручную утомительно, подвержено ошибкам и немного забавно. И у меня такое чувство, что кто-то уже занимался этим в Perl!

Ответы [ 3 ]

2 голосов
/ 22 мая 2010

Может быть, это?

my @list =
    grep {chr ($_) =~ /^\p{Assigned}$/}
    0x27C0..0x27EF;
@list = map { $_ = sprintf ("%X", $_ )} @list;
print "@list\n";

дает мне

27C0 27C1 27C2 27C3 27C4 27C5 27C6 27C7 27C8 27C9 27CA 27D0 27D1 27D2 27D3 
27D4 27D5 27D6 27D7 27D8 27D9 27DA 27DB 27DC 27DD 27DE 27DF 27E0 27E1 27E2 
27E3 27E4 27E5 27E6 27E7 27E8 27E9 27EA 27EB
2 голосов
/ 22 мая 2010

Возможно, вы хотите Unicode :: UCD ?Используйте его подпрограмму charblock, чтобы получить диапазон любого именованного блока.Если вы хотите получить эти имена, вы можете использовать charblocks.

Этот модуль на самом деле является просто интерфейсом к базам данных Unicode, которые уже поставляются с Perl, поэтому, если вам нужно сделать что-то более изощренное, вы можете посмотретьв lib / 5.xy / unicore / UnicodeData.txt или других файлах в том же каталоге, чтобы получить то, что вам нужно.

Вот что я придумал, чтобы создать свой %symbols.Я прохожу все блоки (хотя в этом примере я пропускаю те без «Math» в их имени. Я получаю начальные и конечные кодовые точки и проверяю, какие из них назначены. Из этого я создаю собственное свойство, которое я могу использоватьчтобы проверить, находится ли символ в диапазоне и назначен ли он.

use strict;
use warnings;

digest_blocks();

my $property = 'My::InMiscellaneousMathematicalSymbolsA';

foreach ( 0x27BA..0x27F3 )
    {
    my $in = chr =~ m/\p{$property}/;

    printf "%X is %sin $property\n",
        $_, $in ? '' : ' not ';
    }


sub digest_blocks {
    use Unicode::UCD qw(charblocks);

    my $blocks = charblocks();

    foreach my $block ( keys %$blocks )
        {
        next unless $block =~ /Math/; # just to make the output small

        my( $start, $stop ) = @{ $blocks->{$block}[0] };

        $blocks->{$block} = {
            assigned   => [ grep { chr =~ /\A\p{Assigned}\z/ } $start .. $stop ],
            unassigned => [ grep { chr !~ /\A\p{Assigned}\z/ } $start .. $stop ],
            start      => $start,
            stop       => $stop,
            name       => $block,
            };

        define_my_property( $blocks->{$block} );
        }
    }

sub define_my_property {
    my $block = shift;

    (my $subname = $block->{name}) =~ s/\W//g;
    $block->{my_property} = "My::In$subname"; # needs In or Is

    no strict 'refs';
    my $string = join "\n", # can do ranges here too
        map { sprintf "%X", $_ } 
        @{ $block->{assigned} };

    *{"My::In$subname"} = sub { $string };
    }

Если бы я собирался сделать это много, я бы использовал то же самое для создания исходного файла Perl, который уже имеет пользовательские свойстваЯ могу использовать их сразу в любой из моих работ. Ни одна из данных не должна изменяться, пока вы не обновите данные Unicode.

sub define_my_property {
    my $block = shift;

    (my $subname = $block->{name}) =~ s/\W//g;
    $block->{my_property} = "My::In$subname"; # needs In or Is

    no strict 'refs';
    my $string = num2range( @{ $block->{assigned} } );

    print <<"HERE";
sub My::In$subname {
    return <<'CODEPOINTS';
$string
CODEPOINTS
    }

HERE
    }

# http://www.perlmonks.org/?node_id=87538
sub num2range {
  local $_ = join ',' => sort { $a <=> $b } @_;
  s/(?<!\d)(\d+)(?:,((??{$++1})))+(?!\d)/$1\t$+/g;
  s/(\d+)/ sprintf "%X", $1/eg;
  s/,/\n/g;
  return $_;
}

Это дает мне вывод, подходящий для библиотеки Perl:

sub My::InMiscellaneousMathematicalSymbolsA {
    return <<'CODEPOINTS';
27C0    27CA
27CC
27D0    27EF
CODEPOINTS
    }

sub My::InSupplementalMathematicalOperators {
    return <<'CODEPOINTS';
2A00    2AFF
CODEPOINTS
    }

sub My::InMathematicalAlphanumericSymbols {
    return <<'CODEPOINTS';
1D400   1D454
1D456   1D49C
1D49E   1D49F
1D4A2
1D4A5   1D4A6
1D4A9   1D4AC
1D4AE   1D4B9
1D4BB
1D4BD   1D4C3
1D4C5   1D505
1D507   1D50A
1D50D   1D514
1D516   1D51C
1D51E   1D539
1D53B   1D53E
1D540   1D544
1D546
1D54A   1D550
1D552   1D6A5
1D6A8   1D7CB
1D7CE   1D7FF
CODEPOINTS
    }

sub My::InMiscellaneousMathematicalSymbolsB {
    return <<'CODEPOINTS';
2980    29FF
CODEPOINTS
    }

sub My::InMathematicalOperators {
    return <<'CODEPOINTS';
2200    22FF
CODEPOINTS
    }
0 голосов
/ 22 мая 2010

Я не знаю, почему вы не сказали бы miscellaneous_mathematical_symbols_a => [0x27C0..0x27EF], потому что так определяется стандарт Unicode в соответствии с PDF.

Что вы имеете в виду, когда говорите, что это не "работает"? Если при проверке существования символа в блоке выдается какая-то ошибка, то почему бы просто не отсеять их из блока, когда ваша программа проверки обнаружит ошибку?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...