Как отфильтровать (или заменить) символы Юникода, которые занимают более 3 байтов в UTF-8?

Я столкнулся с той же проблемой. В основном это работает для меня, когда ANALActivity_finish (..) вызывается в основном цикле, поскольку он делает недействительными состояния и завершает само приложение, устанавливая state-> destroyRequested на 1 после вызова ANativeActivity_finish (..) в static void android_app_destroy (struct android_app * android_app) (android_native_app_glue.c C: 173).

void android_main(struct android_app* state) 
{
  // Attach current state if needed
  state->activity->vm->AttachCurrentThread(&state->activity->env, NULL);
  ...
  // our main loop for the app. Will only return once the game is really finished.
  while (true) {
    ...
    while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,(void**)&source)) >= 0) {
      ...
      // Check if we are exiting. Which is the case once we called ANativeActivity_finish(state->activity);
      if (state->destroyRequested != 0) 
      {
         // Quit our app stuff herehere
         // detatch from current thread (if we have attached in the beginning)
         state->activity->vm->DetachCurrentThread();
         // return the main, so we get back to our java activity which calle the nativeactivity
         return;
      }
    }
    if (engine.animating) 
    {
      // animation stuff here
    }
    // if our app told us to finish
    if(Closed)
    {
      ANativeActivity_finish(state->activity);
    }
  }
}

Ну, это слишком поздно для вас, я думаю, но я потратил так много времени на это, потому что я не мог найти султу, поэтому я разместите его здесь для всех, кто сталкивается с теми же проблемами. Подробнее о других сложностях, связанных с вызовами отсоединения и присоединения, можно найти здесь: Доступ к данным APK Asset Android непосредственно в c ++ без Asset Manager и копирование

37
задан Community 23 May 2017 в 10:31
поделиться

5 ответов

Символы Юникода в диапазонах \ u0000- \ uD7FF и \ uE000- \ uFFFF будут иметь кодировку 3 байта (или меньше) в UTF8. Диапазон \ uD800- \ uDFFF предназначен для многобайтового UTF16. Я не знаю Python, но вы должны иметь возможность настроить регулярное выражение для соответствия за пределами этих диапазонов.

pattern = re.compile("[\uD800-\uDFFF].", re.UNICODE)
pattern = re.compile("[^\u0000-\uFFFF]", re.UNICODE)

Отредактируйте добавление Python из сценария Денилсона Са в текст вопроса:

re_pattern = re.compile(u'[^\u0000-\uD7FF\uE000-\uFFFF]', re.UNICODE)
filtered_string = re_pattern.sub(u'\uFFFD', unicode_string)    
34
ответ дан 27 November 2019 в 03:51
поделиться

И просто ради прикола, itertools чудовище :)

import itertools as it, operator as op

def max3bytes(unicode_string):

    # sequence of pairs of (char_in_string, u'\N{REPLACEMENT CHARACTER}')
    pairs= it.izip(unicode_string, it.repeat(u'\ufffd'))

    # is the argument less than or equal to 65535?
    selector= ft.partial(op.le, 65535)

    # using the character ordinals, return 0 or 1 based on `selector`
    indexer= it.imap(selector, it.imap(ord, unicode_string))

    # now pick the correct item for all pairs
    return u''.join(it.imap(tuple.__getitem__, pairs, indexer))
1
ответ дан 27 November 2019 в 03:51
поделиться

Я предполагаю, что это не самый быстрый, но довольно простой ("питонический" :) :

def max3bytes(unicode_string):
    return u''.join(uc if uc <= u'\uffff' else u'\ufffd' for uc in unicode_string)

NB: этот код не учитывает тот факт, что Unicode имеет суррогатные символы в диапазонах U+D800-U+DFFF.

0
ответ дан 27 November 2019 в 03:51
поделиться

Кодировать как UTF-16, затем перекодировать как UTF-8.

>>> t = u'                  
1
ответ дан 27 November 2019 в 03:51
поделиться

Согласно документации MySQL 5.1 : «Наборы символов ucs2 и utf8 не поддерживают дополнительные символы, лежащие вне BMP». Это указывает на то, что может быть проблема с суррогатными парами.

Обратите внимание, что стандарт Unicode 5.2, глава 3 фактически запрещает кодирование суррогатной пары как двух 3-байтовых последовательностей UTF-8 вместо одной 4-байтовой последовательности UTF-8 ... см., Например, стр. 93 "" "Поскольку суррогатные кодовые точки не являются скалярными значениями Unicode, любая последовательность байтов UTF-8, которая в противном случае отображалась бы в кодовые точки D800..DFFF, неправильно сформирована." "" Однако это запрещение, насколько мне известно, в значительной степени неизвестно или игнорируется.

Было бы неплохо проверить, что MySQL делает с суррогатными парами. Если они не будут сохранены, этот код обеспечит достаточно простую проверку:

all(uc < u'\ud800' or u'\ue000' <= uc <= u'\uffff' for uc in unicode_string)

, и этот код заменит любые "гадости" на u \ ufffd :

u''.join(
    uc if uc < u'\ud800' or u'\ue000' <= uc <= u'\uffff' else u'\ufffd'
    for uc in unicode_string
    )
1
ответ дан 27 November 2019 в 03:51
поделиться
Другие вопросы по тегам:

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