【问题标题】:Flutter Dart how to trim if special characters are present?如果存在特殊字符,Flutter Dart 如何修剪?
【发布时间】:2021-07-25 11:31:39
【问题描述】:

我想在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))
            );

这是我现在的修剪实现

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

如何在 dart/flutter 中修剪包含特殊字符 emojis、utf-16 文本的文本?

对于我们自定义的mbTrim 函数,我将给出预期结果的测试用例

text = "testme????socool????abc"

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

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

【问题讨论】:

    标签: flutter dart special-characters utf-16


    【解决方案1】:

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

    您的mbtrim 示例可以实现为:

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

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

    对于更多涉及的编辑,您可能需要使用CharacterRange 类。如果你在循环中做一些复杂的事情,通过更新CharacterRange而不是使用索引通常更方便和高效,所以尝试看看你可以使用CharacterRange并转换回字符串只有当你完成时。

    【讨论】:

    • 对此进行了测试,并在给定的测试用例中正常工作,与 php 中的 mb_string 一样正常工作。已接受作为解决方案,谢谢
    【解决方案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]|\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
    
        }
    

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

    【讨论】:

    • 感谢提示,但这会处理所有可能的 utf-16 特殊字符、所有可能的表情符号等等吗?我不想硬编码一些东西来处理只有?和一组可能的表情符号。想法是这样的,如果我们指定最多修剪 24 个字符,而字符 22-25 是?这个表情符号,那么应该忽略这个,修剪可以在 22 处停止,或者也包括这个表情符号但不分割中间一些特殊字符和然后文本字段崩溃
    • 你的正则表达式也没有修剪任何东西吗?如果我理解正确,只是删除特殊字符。表情符号应该留在那里,但只是修剪不应该像上面的评论那样在中间一个特殊的字符中分割
    • 我会尽量让一个测试用例更容易理解。
    • 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 所以这里的 trim 看起来需要一些自定义实现,像 mbTrim 这样的函数 而不是?可以是任何可用的表情符号或特殊字符应该处理 utf-16,通用实现
    • 是的,这应该删除表情符号和特殊字符,并修剪您必须为其创建或使用另一个库的函数
    猜你喜欢
    • 2014-07-31
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多