Контакт со строкой, содержащей несколько кодировок символов

Прежде всего, вы не должны вызывать HTTP-запрос в componentWillMount(). Вместо этого сделайте это в componentDidMount(), как указано в React docs

Ваш метод в порядке. Однако, основываясь на стратегии контейнерных / презентационных (smart / dump) компонентов, вам лучше выполнить всю выборку данных в компоненте , а затем передать необходимые данные дочерним элементам. Таким образом, было бы намного проще отслеживать ваши запросы, и ваши данные не будут разбросаны.

Альтернативой является использование сторонних библиотек, таких как Redux или Mobx State Tree . Я не уверен насчет Mobx, но Redux сохраняет его за пределами компонентов и делает его доступным для всего приложения в контексте React. Вы должны подумать об использовании этого, так как это чрезвычайно мощный и простой в освоении

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

9
задан Alex McBride 13 October 2008 в 14:26
поделиться

5 ответов

Нет никакой встроенной функциональности для декодирования строки как это, так как это - действительно свой собственный кодек. Просто необходимо разделить строку на тех управляющих символах и декодировать ее соответственно.

Вот (очень медленный) пример такой функции, которая обрабатывает latin1 и shift-JIS:

latin1 = "latin-1"
japanese = "Shift-JIS"

control_l = "\x0c"
control_j = "\n"

encodingMap = {
    control_l: latin1,
    control_j: japanese}

def funkyDecode(s, initialCodec=latin1):
    output = u""
    accum = ""
    currentCodec = initialCodec
    for ch in s:
        if ch in encodingMap:
            output += accum.decode(currentCodec)
            currentCodec = encodingMap[ch]
            accum = ""
        else:
            accum += ch
    output += accum.decode(currentCodec)
    return output

Более быстрая версия могла бы использовать str.split или регулярные выражения.

(Кроме того, как Вы видите в этом примере, "^J" является управляющим символом для "новой строки", таким образом, Ваши входные данные собираются иметь некоторые интересные ограничения.)

4
ответ дан 4 December 2019 в 12:22
поделиться

Вот относительно простой пример того, как делают это...

# -*- coding: utf-8 -*-
import re

# Test Data
ENCODING_RAW_DATA = (
    ('latin_1',    'L', u'Hello'),        # Latin 1
    ('iso8859_2',  'E', u'dobrý večer'),  # Central Europe
    ('iso8859_9',  'T', u'İyi akşamlar'), # Turkish
    ('iso8859_13', 'B', u'Į sveikatą!'),  # Baltic
    ('shift_jis',  'J', u'今日は'),        # Japanese
    ('iso8859_5',  'C', u'Здравствуйте'), # Cyrillic
    ('iso8859_7',  'G', u'Γειά σου'),   # Greek
)

CODE_TO_ENCODING = dict([(chr(ord(code)-64), encoding) for encoding, code, text in ENCODING_RAW_DATA])
EXPECTED_RESULT = u''.join([line[2] for line in ENCODING_RAW_DATA])
ENCODED_DATA = ''.join([chr(ord(code)-64) + text.encode(encoding) for encoding, code, text in ENCODING_RAW_DATA])

FIND_RE = re.compile('[\x00-\x1A][^\x00-\x1A]*')

def decode_single(bytes):
    return bytes[1:].decode(CODE_TO_ENCODING[bytes[0]])

result = u''.join([decode_single(bytes) for bytes in FIND_RE.findall(ENCODED_DATA)])

assert result==EXPECTED_RESULT, u"Expected %s, but got %s" % (EXPECTED_RESULT, result)
7
ответ дан 4 December 2019 в 12:22
поделиться

Я записал бы кодек, который инкрементно просканировал строку и декодировал байты, когда они пришли. По существу необходимо было бы разделить строки на блоки с последовательным кодированием и декодировать их и добавить их к строкам, которые следовали за ними.

3
ответ дан 4 December 2019 в 12:22
поделиться

Я не предполагаю, что у Вас есть какой-либо способ убедить человека, который размещает другую машину для переключения на unicode?

Это - одна из причин, Unicode был изобретен, в конце концов.

1
ответ дан 4 December 2019 в 12:22
поделиться

Определенно необходимо разделить строку сначала на подстроки wih различная кодировка и декодировать каждого отдельно. Только для забавы, обязательной "короткой" версии:

import re

encs = {
    'L': 'latin1',
    'G': 'iso8859-7',
    ...
}

decoded = ''.join(substr[2:].decode(encs[substr[1]])
             for substr in re.findall('\^[%s][^^]*' % ''.join(encs.keys()), st))

(никакая проверка ошибок, и также Вы захотите решить, как обработать '^' символы в подстроках),

2
ответ дан 4 December 2019 в 12:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: