如果存在特殊字符,Flutter Dart 如何 trim?

Flutter Dart how to trim if special characters are present?

我想 trim 文本在 flutter 中,但是文本可能有表情符号和其他特殊字符,并且正常的 trim 方法会导致应用程序崩溃(文本小部件无法解释结果)

示例

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

我对字符串进行了硬编码,但在现实世界中它是用户生成的文本(比如聊天系统),因此我们收到了很多崩溃。

只需 运行 以上内容,您就会遇到崩溃。

在其他语言中,例如 php,可以通过

等变通方法来处理多字节字符串 trimming
$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 ? '' : '...'}';
  }
}

我如何 trim 包含特殊字符表情符号的文本,基本上 dart/flutter 中的 utf-16 文本?

我将为我们的自定义 mbTrim 函数提供 以下预期结果的测试用例

text = "testmesocoolabc"

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

所以逻辑是,如果找到特殊字符,则需要将其完全包含或排除。 (确切地说我可以用 php 在服务器端做什么)

使用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]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])');
    
      if (text.contains(regExp)) {
        text = text.replaceAll(regExp, '');
      }
    
      print(text); /// output: testsomethin la ba kalom

    }

注意:这种业务逻辑,应该有很多测试用例。

有一个 Characters package 可以在不破坏表情符号的情况下处理字符串。

您的 mbtrim 示例可以实现为:

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

对于上面的许多简单任务,Characters(通过 .characters)就足够了。

对于更复杂的编辑,您可能需要使用 CharacterRange class。如果你在循环中做一些复杂的事情,通过更新 CharacterRange 而不是使用索引通常更方便和有效,所以试着看看你是否可以使用 CharacterRange 并转换仅在完成后返回字符串。