【问题标题】:How to format an interploated String如何格式化内插字符串
【发布时间】:2018-06-26 09:37:56
【问题描述】:

我需要像"Send %d seconds ago""Harry like %s", "I think %1$s like %2$s" 这样的格式字符串。这些可以在 Android 中实现,但我不知道如何在 Flutter 的 Dart 中实现。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    Dart 支持字符串插值

    var seconds = 5;
    print("Send $seconds seconds ago");
    
    var harryLikes = 'Silvia';
    var otherName = 'Erik';
    var otherLikes = 'Chess';
    print("Harry like $harryLikes");
    print("I think $otherName like $otherLikes");
    

    还可以使用${...}嵌入更复杂的表达式

    print('Calc 3 + 5 = ${3 + 5}');
    

    数字类型和intl 包提供了更多格式化数字和日期的方法。

    参见示例:

    【讨论】:

    • 但是,这不是问题作者所要求的。从其他来源(如服务器)提取的字符串可以包含通配符,并且在Android(所要求的内容)String.format(stringWithWildcards, one, two, three) 中有效。你会如何在 Dart 中做到这一点?
    • 我不确定这个问题的意思是你解释它。您需要自己处理这些格式部分,例如使用正则表达式查找所有此类格式标记,然后相应地格式化值并用结果替换标记。
    • 如果这不是他想要的,我曾希望得到问题作者的评论,但情况并非总是如此,所以谁知道:D
    • 我认为这不是问题的答案。
    • print里面两个字符串之间的逗号会报错
    【解决方案2】:

    将以下内容添加到您的pubspec.yaml

    dependencies:
      sprintf: "^5.0.0"
    

    然后运行 ​​pub install。

    接下来,导入 dart-sprintf:

    import 'package:sprintf/sprintf.dart';

    示例#

    import 'package:sprintf/sprintf.dart';
    
    void main() {
         double seconds = 5.0;
           String name = 'Dilki';
           List<String> pets = ['Cats', 'Dogs'];
    
           String sentence1 = sprintf('Sends %2.2f seconds ago.', [seconds]);
           String sentence2 = sprintf('Harry likes %s, I think %s likes %s.', [pets[0], name, pets[1]]);
    
           print(sentence1);
           print(sentence2);
    }
    

    输出

    Sends 5.00 seconds ago.

    Harry likes Cats, I think Dilki likes Dogs.

    来源:https://pub.dartlang.org/packages/sprintf

    【讨论】:

      【解决方案3】:

      如前所述,我也使用 sprintf 包,但附带一个方便的 String 类扩展。

      所以在将包依赖 sprintf: "^4.0.0" 添加到 pubspecs.yaml 中的依赖列表后,创建一个新的 Dart 文件,其中包含 Spring 类的扩展,提供如下格式方法:

      extension StringFormatExtension on String {
        String format(var arguments) => sprintf(this, arguments);
      }
      

      现在,在您导入包含 StringFormatExtension 扩展名的 dart 文件后,您可以输入如下内容:

      String myFormattedString = 'Hello %s!'.format('world');
      

      感觉就像在 Java 中(我来自哪里)。

      【讨论】:

        【解决方案4】:

        如果你想要类似于 Android (Today is %1$ and tomorrow is %2$) 的字符串插值,你可以创建一个顶级函数,或者一个可以做类似事情的扩展。在这种情况下,我保持它类似于 Android 字符串,因为我目前正在移植一个 Android 应用程序(插值格式以 1 而不是 0 开头)

        顶级函数

        String interpolate(String string, List<String> params) {
        
          String result = string;
          for (int i = 1; i < params.length + 1; i++) {
            result = result.replaceAll('%${i}\$', params[i-1]);
          }
        
          return result;
        }
        

        然后您可以调用interpolate(STRING_TO_INTERPOLATE, LIST_OF_STRINGS),您的字符串将被插值。

        扩展

        您可以创建一个类似于 Android String.format() 的扩展函数

        extension StringExtension on String {
            String format(List<String> params) => interpolate(this, params);
        }
        

        这将允许您致电text.format(placeHolders)

        测试

        浓度证明的几个测试:-

        test('String.format extension works', () {
            // Given
            const String text = 'Today is %1\$ and tomorrow is %2\$';
            final List<String> placeHolders = List<String>()..add('Monday')..add('Tuesday');
            const String expected = 'Today is Monday and tomorrow is Tuesday';
        
            // When
            final String actual = text.format(placeHolders);
        
            // Then
            expect(actual, expected);
          });
        

        【讨论】:

          【解决方案5】:

          我是用老式的方式做的

          String url = "https://server.com/users/:id:/view";
          print(url.replaceAll(":id:", "69");
          

          【讨论】:

            【解决方案6】:

            你也可以有这样简单的东西:

            • 用法
            interpolate('Hello {#}{#}, cool {#}',['world','!','?']);
            // Hello world!, cool ?
            
            • 功能
              static const needleRegex = r'{#}';
              static const needle = '{#}';
              static final RegExp exp = new RegExp(needleRegex);
            
              static String interpolate(String string, List l) {
                Iterable<RegExpMatch> matches = exp.allMatches(string);
            
                assert(l.length == matches.length);
            
                var i = -1;
                return string.replaceAllMapped(exp, (match) {
                  print(match.group(0));
                  i = i + 1;
                  return '${l[i]}';
                });
              }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-07-05
              • 1970-01-01
              • 2016-08-30
              • 2013-03-17
              • 1970-01-01
              • 2017-11-09
              • 2019-03-04
              • 1970-01-01
              相关资源
              最近更新 更多