flutter 如何设置插入字符串的格式

r8uurelv  于 2023-03-13  发布在  Flutter
关注(0)|答案(7)|浏览(194)

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

6qfn3psc

6qfn3psc1#

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包提供了更多格式化数字和日期的方法。
参见示例:

ztmd8pv5

ztmd8pv52#

将以下内容添加到pubspec.yaml

dependencies:
  sprintf: "^5.0.0"

然后运行pub安装。
接下来,导入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

ljsrvy3e

ljsrvy3e3#

如果你想要类似于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);
  });
gupuwyp2

gupuwyp24#

如前所述,我也使用sprintf包,但沿着使用String类的一个方便的扩展。
因此,在pubspecs.yaml中将包依赖项sprintf: "^4.0.0"添加到依赖项列表之后,创建一个新的Dart文件,其中包含Spring类的扩展名,该Spring类提供如下格式方法:

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

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

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

感觉就像在 java (我来自的地方)。

hpcdzsge

hpcdzsge5#

我用老办法做的

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

7z5jn7bk6#

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

  • 用途
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]}';
    });
  }
sg3maiej

sg3maiej7#

现在有一个包,它的工作原理与Python的format函数非常相似。
https://pub.dev/packages/format
我认为通常更好的解决方案是@Günter Zöchbauer提出的解决方案,但是像format这样的包也有它的位置。我发现当我想要一些变量可能改变的预存错误消息时,它最有帮助。
下面是一个用法示例:

import 'package:format/format.dart';

// Base of string defined BEFORE the "seconds" variable which can be created and subbed in later
const String MESSAGE = 'Send {seconds} seconds ago';

// Define "seconds"
int seconds = 1234;

// Sub in the value of "seconds".  Prints "Send 1234 seconds ago"
print(MESSAGE.format({'seconds': seconds});

可接受的答案不允许已经创建的字符串包含一个变量,format包比其他使用replaceAll或类似的答案更干净地进行替换。

相关问题