【发布时间】:2018-06-26 09:37:56
【问题描述】:
我需要像"Send %d seconds ago"、"Harry like %s", "I think %1$s like %2$s" 这样的格式字符串。这些可以在 Android 中实现,但我不知道如何在 Flutter 的 Dart 中实现。
【问题讨论】:
我需要像"Send %d seconds ago"、"Harry like %s", "I think %1$s like %2$s" 这样的格式字符串。这些可以在 Android 中实现,但我不知道如何在 Flutter 的 Dart 中实现。
【问题讨论】:
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 包提供了更多格式化数字和日期的方法。
参见示例:
【讨论】:
String.format(stringWithWildcards, one, two, three) 中有效。你会如何在 Dart 中做到这一点?
将以下内容添加到您的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.
【讨论】:
如前所述,我也使用 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 中(我来自哪里)。
【讨论】:
如果你想要类似于 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);
});
【讨论】:
我是用老式的方式做的
String url = "https://server.com/users/:id:/view";
print(url.replaceAll(":id:", "69");
【讨论】:
你也可以有这样简单的东西:
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]}';
});
}
【讨论】: