Конвертировать символы ASCII в латинские буквы Unicode FULLWIDTH на Python? - PullRequest
12 голосов
/ 30 ноября 2011

Сможете ли вы легко конвертировать символы ASCII и их широкоформатные азиатские символы Unicode?Как:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~

до

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!゛#$%&()*+、ー。/:;〈==〉?@[\\]^_‘{|}~

Ответы [ 6 ]

9 голосов
/ 30 ноября 2011

Эти "широкие" символы называются FULLWIDTH LATIN LETTER: http://www.unicodemap.org/range/87/Halfwidth%20and%20Fullwidth%20Forms/

Они имеют диапазон 0xFF00 - -0xFFEF. Вы можете создать справочную таблицу или просто добавить 0xFEE0 в код ASCII.

8 голосов
/ 01 декабря 2011

Диапазон замены ASCII полной ширины начинается с U + FF01, а не U + FF00.U + FF00 (странно) не определен.Чтобы получить полный пробел, вам нужно использовать U + 3000 IDEOGRAPHIC SPACE.Не полагайтесь на то, что выглядит как как то, что вам нужно, с последующей визуальной проверкой символов для проверки соответствия - unicodedata.name ваш друг.Этот код:

# coding: utf-8
from unicodedata import name as ucname

# OP
normal = u"""0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~"""
wide = u"""0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!゛#$%&()*+、ー。/:;〈=〉?@[\\]^_‘{|}~"""
# above after editing (had = twice)
widemapOP = dict((ord(x[0]), x[1]) for x in zip(normal, wide))

# Ingacio V
normal = u' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~'
wide = u' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!゛#$%&()*+、ー。/:;〈=〉?@[\\]^_‘{|}~'
widemapIV = dict((ord(x[0]), x[1]) for x in zip(normal, wide))

# JM
widemapJM = dict((i, i + 0xFF00 - 0x20) for i in xrange(0x21, 0x7F))
widemapJM[0x20] = 0x3000 # IDEOGRAPHIC SPACE

maps = {'OP': widemapOP, 'IV': widemapIV, 'JM': widemapJM}.items()

for i in xrange(0x20, 0x7F):
    a = unichr(i)
    na = ucname(a, '?')
    for tag, widemap in maps:
        w = a.translate(widemap)
        nw = ucname(w, '?')
        if nw != "FULLWIDTH " + na:
            print "%s: %04X %s => %04X %s" % (tag, i, na, ord(w), nw)

при запуске показывает, что у вас есть действительно получено: некоторые отсутствующие отображения и некоторые уникальные отображения:

JM: 0020 SPACE => 3000 IDEOGRAPHIC SPACE
IV: 0020 SPACE => 3000 IDEOGRAPHIC SPACE
OP: 0020 SPACE => 0020 SPACE
IV: 0022 QUOTATION MARK => 309B KATAKANA-HIRAGANA VOICED SOUND MARK
OP: 0022 QUOTATION MARK => 309B KATAKANA-HIRAGANA VOICED SOUND MARK
IV: 0027 APOSTROPHE => 0027 APOSTROPHE
OP: 0027 APOSTROPHE => 0027 APOSTROPHE
IV: 002C COMMA => 3001 IDEOGRAPHIC COMMA
OP: 002C COMMA => 3001 IDEOGRAPHIC COMMA
IV: 002D HYPHEN-MINUS => 30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK
OP: 002D HYPHEN-MINUS => 30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK
IV: 002E FULL STOP => 3002 IDEOGRAPHIC FULL STOP
OP: 002E FULL STOP => 3002 IDEOGRAPHIC FULL STOP
IV: 003C LESS-THAN SIGN => 3008 LEFT ANGLE BRACKET
OP: 003C LESS-THAN SIGN => 3008 LEFT ANGLE BRACKET
IV: 003E GREATER-THAN SIGN => 3009 RIGHT ANGLE BRACKET
OP: 003E GREATER-THAN SIGN => 3009 RIGHT ANGLE BRACKET
IV: 005C REVERSE SOLIDUS => 005C REVERSE SOLIDUS
OP: 005C REVERSE SOLIDUS => 005C REVERSE SOLIDUS
IV: 0060 GRAVE ACCENT => 2018 LEFT SINGLE QUOTATION MARK
OP: 0060 GRAVE ACCENT => 2018 LEFT SINGLE QUOTATION MARK
2 голосов
/ 30 ноября 2011

Да.

>>> normal = u' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~'
>>> wide = u' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!゛#$%&()*+、ー。/:;〈=〉?@[\\]^_‘{|}~'
>>> widemap = dict((ord(x[0]), x[1]) for x in zip(normal, wide))
>>> print u'Hello, world!'.translate(widemap)
Hello、 world!
1 голос
/ 03 июля 2014

Да; в Python 3 самым чистым является использование str.translate и str.maketrans :

HALFWIDTH_TO_FULLWIDTH = str.maketrans(
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&()*+,-./:;<=>?@[]^_`{|}~',
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!゛#$%&()*+、ー。/:;〈=〉?@[]^_‘{|}~')

def halfwidth_to_fullwidth(s):
    return s.translate(HALFWIDTH_TO_FULLWIDTH)

В Python 2 str.maketrans вместо этого string.maketrans и не работает с символами Юникода, поэтому вам нужно создать словарь, как отмечает Игнасио Васкес выше.

0 голосов
/ 30 ноября 2011

Это идет в одну сторону:

#!/usr/bin/env perl
# uniwide
use utf8;
use strict;
use warnings;
use open qw(:std :utf8);

while (<>) {    
    s/\s/\x{A0}\x{A0}/g if tr
      <!"#$%&´()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£>
      <!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£>;;    
} continue {
      print;   
} 

close(STDOUT) || die "can't close stdout: $!";

И это касается другого:

#!/usr/bin/env perl
# uninarrow
use utf8;
use strict;
use warnings;
use open qw(:std :utf8);

while (<>) {     
    s/  / /g if tr
      <!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£>
      <!"#$%&´()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£>    
} continue {
      print;    
} 

close(STDOUT) || die "can't close stdout: $!";
0 голосов
/ 30 ноября 2011

UTF-8 Коды Unicode для ASCII точно такие же.Для UTF-16 добавить ноль до / после (LE / BE)

Или в python mystr.encode("utf-8")

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