I need format string like "Send %d seconds ago"
, "Harry like %s", "I think %1$s like %2$s"
. These can be implemented in Android, but i don't how to implement in Dart of Flutter.
问题:
回答1:
Add the following to your pubspec.yaml
dependencies:
sprintf: "^4.0.0"
then run pub install.
Next, import dart-sprintf:
import 'package:sprintf/sprintf.dart';
Example #
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);
}
Output
Sends 5.00 seconds ago.
Harry likes Cats, I think Dilki likes Dogs.
Source: https://pub.dartlang.org/packages/sprintf
回答2:
Dart supports string interpolation
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");
Also more complex expressions can be embedded with ${...}
print('Calc 3 + 5 = ${3 + 5}');
The number types and the intl
package provide more methods to format numbers and dates.
See for example:
- https://www.dartdocs.org/documentation/intl/latest/intl/NumberFormat-class.html
- Currency format in dart
回答3:
If you want String interpolation similar to Android (Today is %1$ and tomorrow is %2$
), you can create a top level function, or an extension that can do something similar. In this instance I keep it similar to Android strings as I'm currently porting an Android app (Interpolatation formatting starts with 1 rather than 0)
Top Level Function
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;
}
You can then call interpolate(STRING_TO_INTERPOLATE, LIST_OF_STRINGS)
and you string would be interpolated.
Extensions
You can create an extension function that does something similarish to Android String.format()
extension StringExtension on String {
String format(List<String> params) => interpolate(this, params);
}
This would then allow you to call text.format(placeHolders)
Testing
Couple of tests for proof of concent:-
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);
});
回答4:
you could also have something simple like this:
- Usage
interpolate('Hello {#}{#}, cool {#}',['world','!','?']);
// Hello world!, cool ?
- Function
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]}';
});
}