Working with Strings in Dart/Flutter

June 14, 2021 No comments Dart Flutter Strings

1. Introduction

Dart since it was selected as the main programming language for the Flutter framework is becoming more and more popular. This language is universal just like Java and could be used on any platform. In this tutorial, we will cover operations on strings in Dart/Flutter. Strings are the most used objects in any language, in Dart string holds a sequence of UTF-16 code units.

2. Create a string in Dart/Flutter

2.1. Create normal strings

To create a simple string in Dart/Flutter we can use either single or double quotes:

var s1 = 'FrontBackend.com - single quotes are the best for string literals.';
var s2 = "FrontBackend.com - good practice is to use double quotes only for strings containing 'single quotes'.";
var s3 = 'FrontBackend.com - it\'s easy to escape the string delimiter.';
var s4 = "FrontBackend.com - It's even easier to use the other delimiter.";

The recommended way is to use single quotes and double quotes only for a string that contains single quotes inside.

2.2. Create raw strings

In order to create raw strings - without special treatment use the r prefix like in the following example:

void main(List<String> arguments) {
  String raws1 = r'FrontBackend.com\n This is a raw string';
  print(raws1);
}

The output will be:

FrontBackend.com\n This is a raw string

2.3. Create multi-lined strings

To create a multi-line string we need to use a triple quote with either single or double quotation marks:

void main(List<String> arguments) {
  var s1 = '''
We can create
multi-line strings like this one,
using 3 single quotes.
''';

  print(s1);

  var s2 = """This is also a
multi-line string, using double quote.""";

  print(s2);
}

The output will be:

We can create
multi-line strings like this one,
using 3 single quotes.

This is also a
multi-line string, using double quote.

2.4. Strings with special characters from UTF-32

If we want to create a string in Dart/Flutter with special characters we need to use syntax with \uXXXX, \u{XX} or \u{XXXXX}.

void main(List<String> arguments) {
  var u1 = 'Miscellaneous symbols: \u{266A} \u{266B} \u{266C} \u{266D} \u{266E} \u{266F}';
  print(u1); // Miscellaneous symbols: ♪ ♫ ♬ ♭ ♮ ♯

  var u2 = 'Greek characters: \u{3B1} \u{3B2} \u{3B3} \u{3B4} \u{3B5}';
  print(u2); // Greek characters: α β γ δ ε
}

2.5. Using expressions inside a string

We can put the value of an expression inside a string by using ${expression} syntax. Dart will call the .toString() method in order to get the string corresponding to an object. When the expression is an identifier we can skip {}.

void main(List<String> arguments) {
  var str1 = 'World';
  var str2 = 'Hello $str1!';

  print(str2); // Hello World!
}

3. Operations on strings in Dart/Flutter

3.1. Get character from string by index

For this kind of operations we must use the [] operator:

void main(List<String> arguments) {
  var str = 'FrontBackend.com';
  print(str[0]); // F
  print(str[5]); // B
}

We could use that to create a simple method that will convert first letter of a string and present it in uppercase:

void main(List<String> arguments) {
  var s = 'frontbackend.com';
  print(capitalize(s)); // Frontbackend.com
}

String capitalize(String s) => s[0].toUpperCase() + s.substring(1);

3.2. Get a substring of a string

To substring we use substring(start, end) method:

void main(List<String> arguments) {
  var str = 'FrontBackend.com';

  print(str.substring(0, 5)); // Front
  print(str.substring(5, 12)); // Backend
  print(str.substring(13)); // com
}

The signature of this method looks like the following:

String substring(int start, [int? end]);

As you can see the end parameter is not required, and if it is not present substring method will take the end of the string by default.

3.3. Get the position of a character or substring (first match)

Method indexOf() could be used to get an index of a character or other string in string:

void main(List<String> arguments) {
  var s = 'FrontBackend.com';
  print(s.indexOf('F'));           // 0
  print(s.indexOf('end'));          // 9
  print(s.indexOf(RegExp(r'd.'))); // 11
  print(s.indexOf('com'));        // 13
}

If given character or a string is notfound, method indexOf() returns -1.

3.4. Get the position of a character or substring (last match)

We can do this by using lastIndexOf() method:

void main(List<String> arguments) {
  var s = 'FrontBackend.com';
  print(s.lastIndexOf('n'));           // 10
  print(s.lastIndexOf('end'));          // 9
}

The same as indexOf() method the lastIndexOf() will return -1 if there is no match.

3.5. Transform string to uppercase and lowercase

To transform a string we use toUpperCase() and toLowerCase():

void main(List<String> arguments) {
  var s = 'FrontBackend.com';
  print(s.toLowerCase()); // frontbackend.com
  print(s.toUpperCase()); // FRONTBACKEND.COM
}

Note that these methods don't change the original string.

3.6. Check if string is empty

In Dart we have dedicated properties isEmpty and isNotEmpty to check if a String is empty or not:

void main(List<String> arguments) {
  var str = '';
  print(str.isEmpty); // true
  print(str.isNotEmpty); // false
}

3.7. Check if a string contains another string

To check if a string contains another string we could use contains() method:

void main(List<String> arguments) {
  var str = 'FrontBackend.com';
  print(str.contains("other")); // false
  print(str.contains("Backend")); // true
  print(str.contains("backend")); // false
}

Note that contains() method take two parameters:

  • a substring - that could be a String object or a RegExp,
  • the startIndex (optional) - the index from which the method matches the substring.
void main(List<String> arguments) {
  var str = 'FrontBackend.com';

  print(str.contains('B')); // true
  print(str.contains(RegExp(r'[a-z]'))); // true
  print(str.contains('F', 3)); // false
}

3.8. Check if a string starts or ends with a specified character/string

We can do this using endsWith() and startsWith() methods:

void main(List<String> arguments) {
  var str = 'FrontBackend.com';

  print(str.startsWith('F')); // true
  print(str.startsWith('Backend')); // false
  print(str.startsWith('Front')); // true

  print(str.endsWith('m')); // true
  print(str.endsWith('F')); // false
  print(str.endsWith('.com')); // true
}

3.9. Concatenating strings in Dart/Flutter

To concatenate strings we could use interpolation, separate strings in one statement or + operator:

void main(List<String> arguments) {
  var str1 = 'FrontBackend';
  var str2 = '.com';

  var s1 = '$str1$str2'; // interpolation
  var s2 = '$str1' '$str2'; // separated in one statement
  var s3 = str1 + str2; // operator

  print(s1); // FrontBackend.com
  print(s2); // FrontBackend.com
  print(s3); // FrontBackend.com
}

3.10. Multiply a string in Dart/Flutter

We can use Dart string operator *, that can multiply a string specified number of times:

void main(List<String> arguments) {
  var str1 = 'FrontBackend';

  print(str1 * 2); // FrontBackendFrontBackend
}

3.11. Splitting the string in Dart/Flutter

In Dart the method split() splits the string at matches of pattern and returns a list of substrings:

void main(List<String> arguments) {
  var str1 = 'FrontBackend.com';
  var str2 = "Hello world!";

  print(str1.split('.')); // ['FrontBackend', 'com']
  print(str1.split(RegExp('Backend'))); // ['Front', '.com']
  print(str1.split('')); // ['F', 'r', 'o', 'n', 't', 'B', 'a', 'c', 'k', 'e', 'n', 'd', '.', 'c', 'o', 'm']

  print(str2.split(' ')); // ['Hello', 'world!']
}

Note that if this string is empty, the result is an empty list if the pattern matches the empty string, and it is [""] if the pattern doesn't match.

void main(List<String> arguments) {
  var string = '';

  print(string.split('')); // []
  print(string.split('').length); // 0

  print(string.split("a")); // ['']
  print(string.split("a").length); // 1
}

3.12. Splits the string, converts its parts, and combines them into a new string

The Dart has a dedicated method to split the string, convert its parts, and combines them - splitMapJoin(...).

This is the signature of this method:

String splitMapJoin(Pattern pattern,
    {String onMatch(Match match), String onNonMatch(String nonMatch)});

The method takes three parameters:

  • pattern - that could be a String or a RegExp object,
  • onMatch method (optional) - converts each match to a string,
  • onNonMatch method (optional) - converts each non-matched part to a string.
void main(List<String> arguments) {
  var input = 'FrontBackend.com';

  var result = input.splitMapJoin(RegExp(r'[\.]+'),
      onMatch: (m) => '.subdomain${m.group(0)}',
      onNonMatch: (n) => '${n.toLowerCase()}');

  print(result); // frontbackend.subdomain.com
}

3.13. Justify string in Dart/Flutter

There are two methods in Dart to justify text:

  • padLeft(int width, [String padding = ' ']) - pads the string on the left if it is shorter than width.
  • padRight(int width, [String padding = ' ']) - pads this string on the right if it is shorter than width.
void main(List<String> arguments) {
  var input = 'front';

  print(input.padLeft(10)); // '     front'
  print(input.padLeft(10, '+')); // '+++++front'
  print(input.padLeft(5)); // 'front'

  print(input.padRight(10)); // 'front     '
  print(input.padRight(10, '-')); // 'front-----'
  print(input.padRight(2)); // 'front'
}

3.14. Trim string in Dart/Flutter

We have three methods to trim a string in Dart/Flutter:

  • trimLeft() - returns the string without any leading whitespace,
  • trimRight() - returns the string without any trailing whitespace,
  • trim() - returns the string without any leading and trailing whitespace.
void main(List<String> arguments) {
  var str = '\tfrontbackend.com    ';

  print(str.trimLeft()); // 'frontbackend.com    '
  print(str.trimRight()); // '    frontbackend.com'
  print(str.trim()); // 'frontbackend.com'
}

3.15. String replace the first match in Dart/Flutter

In Dart we have two methods to replace strings (the first match):

  • replaceFirst(Pattern from, String to, [int startIndex = 0]) - returns a new string in which the first occurrence of from in this string is replaced with to, starting from startIndex,
  • replaceFirstMapped(Pattern from, String replace(Match match), [int startIndex = 0]) - returns a new String in which, the first match of from is replaced by the result of replace(Match match) function.
void main(List<String> arguments) {
  var str = 'frontbackend.com';

  print(str.replaceFirst('r', 'R')); // fRontbackend.com
  print(str.replaceFirst('N', 'N', 5)); // frontbackeNd.com
  print(str.replaceFirst(RegExp(r'backend'), 'server')); // frontserver.com

  print(str.replaceFirstMapped('t', (m) => '${m.group(0)}-')); // front-backend.com
  print(str.replaceFirstMapped('n', (m) => '[${m.group(0)}]', 5)); // frontbacke[n]d.com
}

3.16. Replace all matches in Dart/Flutter

To replace all substrings in Dart we can use two methods:

  • replaceAll(Pattern from, String replace) - replaces all substrings that match from with replace,
  • replaceAllMapped(Pattern from, String replace(Match match)) - replace all substrings that match from by a string computed from the match.
void main(List<String> arguments) {
  var str = 'frontbackend.com';

  print(str.replaceAll('n', '[N]')); // fro[N]tbacke[N]d.com

  print(str.replaceAllMapped(RegExp(r'n'), (m) => m.group(0).toString() + '_')); // fron_tbacken_d.com
}

3.17. Replace in range method

In Dart we have also a third method that could replace in the range:

replaceRange(int start, int end, String replacement)

This method replaces the substring from start to end with replacement. The start and end indices must specify a valid range of this string.

void main(List<String> arguments) {
  var str = 'frontbackend.com';
  print(str.replaceRange(2, 4, 'ooooooooon')); // frooooooooontbackend.com
}

4. Conclusion

In this tutorial, we presented many operations on strings in Dart/Flutter. This programming language is very developer-friendly and provides very useful methods to manipulate text. Creators know that these are the common operations in any application.

{{ message }}

{{ 'Comments are closed.' | trans }}