Трепещущий дротик как обрезать, если присутствуют специальные символы?

#flutter #dart #special-characters #utf-16

Вопрос:

Я хотел бы обрезать текст в flutter, но в тексте могут быть смайлики и другие специальные символы, и обычный метод обрезки приведет к сбою приложения (текстовый виджет не может интерпретировать результат).

Пример

 Text(
                            trim("testsomethin la ba kalom 😊😊😊", 28),
                            style: TextStyle(
                              fontSize: Dimen.mediumText,
                            ),
                            overflow: TextOverflow.ellipsis,
                          ),
 

Я жестко закодировал строку, но в реальном мире это пользовательский текст (скажем, система чата), и из-за этого мы получили много сбоев.

Просто выполните описанное выше, и вы испытаете сбой.

На других языках php , например, например, можно выполнять многобайтовую обрезку строк с помощью обходных путей, таких как

 $userText = "testsomethin la ba kalom 😊😊😊";
$trimed = mb_substr(
                $userText,
                0,
                min(28, strlen($userText))
            );
 

Теперь это моя реализация trim

 class FormatMixin {
  trim(String s, int trimLength) {
    return '${s.substring(0, s.length <= trimLength ? s.length : trimLength)}${s.length <= trimLength ? '' : '...'}';
  }
}

 

Как я могу обрезать текст, содержащий специальные символы смайликов, текст utf-16 в основном в виде дротика/флаттера ?

Ниже я приведу тестовые примеры ожидаемого результата для нашей пользовательской mbTrim функции:

 text = "testme😊socool😊abc"

1. mbTrim(text, 6) = "testme"
2. mbTrim(text, 7) = "testme😊"
3. mbTrim(text, 8) = "testme😊s"
 

Таким образом, логика заключается в том, что если найден специальный символ, его необходимо полностью включить или исключить. (точно, что я мог бы сделать на стороне сервера с php)

Ответ №1:

Существует пакет символов для обработки строк без нарушения смайликов.

Ваш mbtrim пример может быть реализован следующим образом:

 String mbtrim(String text, int length) =>
   text.characters.take(length).toString();
 

Для многих простых задач, подобных приведенным выше, Characters (via .characters ) достаточно.

Для более сложного редактирования вам, возможно, потребуется использовать CharacterRange класс. Если вы делаете что-то сложное в цикле, часто удобнее и эффективнее делать это путем обновления CharacterRange , а не с помощью индексов, поэтому постарайтесь понять, можете ли вы работать с CharacterRange и преобразовать обратно в строку только тогда, когда закончите.

Комментарии:

1. Протестировал это и правильно работал с данными тестовыми случаями, о которых идет речь, работая, как и ожидалось, так же, как mb_string в php. Принято в качестве решения, спасибо

Ответ №2:

Воспользуйся RegExp

   void main() {
      String text = "testsomethin la ba kalom 😊😊😊";
      final RegExp regExp = RegExp(
          r'(?:[u2700-u27bf]|(?:ud83c[udde6-uddff]){2}|[ud800-udbff][udc00-udfff]|[u0023-u0039]ufe0f?u20e3|u3299|u3297|u303d|u3030|u24c2|ud83c[udd70-udd71]|ud83c[udd7e-udd7f]|ud83cudd8e|ud83c[udd91-udd9a]|ud83c[udde6-uddff]|ud83c[ude01-ude02]|ud83cude1a|ud83cude2f|ud83c[ude32-ude3a]|ud83c[ude50-ude51]|u203c|u2049|[u25aa-u25ab]|u25b6|u25c0|[u25fb-u25fe]|u00a9|u00ae|u2122|u2139|ud83cudc04|[u2600-u26FF]|u2b05|u2b06|u2b07|u2b1b|u2b1c|u2b50|u2b55|u231a|u231b|u2328|u23cf|[u23e9-u23f3]|[u23f8-u23fa]|ud83cudccf|u2934|u2935|[u2190-u21ff])');
    
      if (text.contains(regExp)) {
        text = text.replaceAll(regExp, '');
      }
    
      print(text); /// output: testsomethin la ba kalom

    }
 

Примечание: Для такого рода бизнес-логики должно быть много тестовых примеров.

Комментарии:

1. спасибо за подсказку, но будет ли это обрабатывать все возможные специальные символы utf-16, все возможные смайлики и так далее ? Я не хочу жестко кодировать что-то, чтобы обрабатывать только 😊 и набор возможных смайликов. Идея заключается в следующем, если мы указываем обрезать не более 24 символов, а символ 22-25-это 😊 этот смайлик, то это следует игнорировать, и обрезка может остановиться на 22, или включить этот смайлик также, но не разделять посередине какой-то специальный символ, а затем сбой текстового поля

2. Кроме того, ваше регулярное выражение ничего не обрезает правильно ? Это просто удаление специальных символов, если я правильно понял. Смайлики должны оставаться там, но просто обрезка не должна разделяться посередине одним специальным символом, как в приведенном выше комментарии

3. Я постараюсь упростить понимание с помощью одного тестового набора.

4. text = "testme😊afteremoji" trim(text, 6) should result in testme, trim(text, 7) should result in testme😊, trim(text,8) should result in testme😊a Итак, здесь, похоже, нужна какая-то пользовательская реализация, функция, подобная mbTrim И вместо😊, может быть любым доступным смайликом или специальным символом, должна обрабатываться utf-16, универсальная реализация

5. да, это должно удалить смайлики и специальные символы, а также функцию обрезки, для которой вам нужно создать или использовать другую библиотеку