5

我最近更频繁地使用 unicode,想知道是否有命令行工具可以在其形式之间转换 unicode。

很高兴能够说:

uni_convert "☃" --string

并且知道该字符串在 unicode 中定义为“SNOWMAN”。

4

3 回答 3

7

Perl 的Unicode-Tussle发行版带有有用的uniprops.

$ uniprops '☃'
U+2603 ‹☃› \N{SNOWMAN}
...

$ uniprops 'U+2603'
U+2603 ‹☃› \N{SNOWMAN}
...

$ uniprops 'SNOWMAN'
U+2603 ‹☃› \N{SNOWMAN}
...

如果您正在编写代码,您将需要charnames

Input  To get $code
=====  ==============================
$char  ord($char)
$name  charnames::vianame($name)

Input  To get $char                    
=====  ==============================
$code  chr($code)
$name  chr(charnames::vianame($name))

Input  To get $name
=====  ==============================
$code  charnames::viacode($code)
$char  charnames::viacode(ord($char))

vianame接受官方别名(例如LFfor LINEFEED)。U+如果希望接受它,您需要自己解析符号。( $code = hex(s/^U\+//r);)

例子:

use strict;
use warnings;
use feature      qw( say );
use experimental qw( regex_sets );

use utf8;                              # Source encoded using UTF-8.
use open ":std", ":encoding(UTF-8)";   # Terminal provides/expects UTF-8.

use charnames qw( :full );
use Encode    qw( decode_utf8 );

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

my $s = decode_utf8($ARGV[0]);

for my $cp ( unpack "W*", $s ) {
   my $ch = chr($cp);
   if ( $ch =~ /(?[ \p{Print} - \p{Mark} ])/ ) {   # Not sure if good enough.
      printf "‹%s› ", $ch;
   } else {
      print "--- ";
   }

   printf "U+%X ", $cp;

   say charnames::viacode($cp);
}
$ uni_id ☃
‹☃› U+2603 SNOWMAN

$ uni_id çà
‹ç› U+E7 LATIN SMALL LETTER C WITH CEDILLA
‹à› U+E0 LATIN SMALL LETTER A WITH GRAVE

其他资源:

于 2021-12-09T21:32:52.400 回答
2

这是一个 awk 来做到这一点。

从提供最新名称的 unicode.org下载此文件。

然后:

q=$(printf '%x\n' \'☃)
awk '/^[[:xdigit:]]+/{
    str=$0
    sub(/^[[:xdigit:]]+[[:blank:]]+/,"",str)
    names[$1]=str
}
END{ print names[q] }
' q="$q" names.txt

印刷:

SNOWMAN

如果你想走另一条路:

cp=$(awk '/^[[:xdigit:]]+/{
    str=$0
    sub(/^[[:xdigit:]]+[[:blank:]]+/,"",str)
    other_names[str]=$1
}
END{ print other_names[q] }
' q="SNOWMAN" names.txt)

echo -e "\u${cp}"

印刷:

如果您有 GNU awk,您可以轻松地将十六进制索引转换为十进制并可以从内部打印。这允许使用单个源文件并通过定义q或以一种方式或另一种方式使用r

gawk '/^[[:xdigit:]]+/{
    str=$0
    sub(/^[[:xdigit:]]+[[:blank:]]+/,"",str)
    names[$1]=str
    other_names[str]=$1
}
END{ print q ? names[q] : sprintf("%c", strtonum("0x" other_names[r])) }
' r='SNOWMAN' names.txt
☃

gawk '/^[[:xdigit:]]+/{
    str=$0
    sub(/^[[:xdigit:]]+[[:blank:]]+/,"",str)
    names[$1]=str
    other_names[str]=$1
}
END{ print q ? names[q] : sprintf("%c", strtonum("0x" other_names[r])) }
' q=$(printf '%x\n' \'☃) names.txt
SNOWMAN
于 2021-12-09T17:08:02.337 回答
2

我将代码分成一个文件并创建了一个 repo: https ://github.com/poti1/uni_convert

于 2021-12-09T16:44:34.600 回答