Strings in Dart
By Syncfusion®, Inc. · Last updated
How to create strings, put values inside them, compare, search, cut, change, split and join them, build long text with StringBuffer, and handle Unicode and emoji.
What Is a String?
String = a piece of text: letters, digits, spaces, symbols and emoji, in order.
For example:
- a name:
'Asha' - a sentence:
'Today is Sports Day.' - digits you never do maths on:
'600001'
Each character has a position, starting at 0, just like a list (see Lists).
Simple lesson: a String is text, and Dart gives you many tools to search, cut and change it.
A Real-World Example
The school app shows "Welcome, ASHA!" on the home screen.
- The name comes from the database as
' asha ', with extra spaces. - The app trims the spaces, makes it upper case, and puts it inside a sentence.
Three string tools, one line of code. Try the tools yourself:
Every Run box on this page runs on the course's Dart runner in your browser.
Strings never change in place. Every method gives you a new string.
What You Will Learn
In this lesson, you will learn:
- How to create strings, including multi-line and raw strings.
- String properties, interpolation, joining and comparing.
- How to search, extract and change parts of a string.
- How to change case, trim, split and join.
- How to build long text with
StringBuffer, and handle Unicode and emoji.
String Fundamentals
Creating Strings
Four ways to write a string
Single, double, multi-line and raw
void main() {
var school = 'Green Valley';
var quote = "It's Sports Day!";
var address = '''Green Valley School
12, MG Road
Pune''';
var path = r'C:\notes\new $file';
print(school);
print(quote);
print(address);
print(path);
}
Escape sequence = a backslash code for a special character, like \n (new line), \t (tab), \' (a quote) or \$ (a dollar sign).
Simple lesson: use single quotes normally, three quotes for many lines, and r'' to keep backslashes.
String Properties
| Property | Gives | 'Asha' gives |
|---|---|---|
length | number of UTF-16 units | 4 |
isEmpty | true if it is '' | false |
isNotEmpty | true if it has text | true |
codeUnits | the number code of each unit | [65, 115, 104, 97] |
runes | the Unicode code of each character | (65, 115, 104, 97) |
String properties
void main() {
var name = 'Asha';
print(name.length);
print(name.isEmpty);
print(''.isEmpty);
print(name.codeUnits);
print(name[0]);
print(name[name.length - 1]);
}
name[0] gives the first character. The last one is at length - 1.
Simple lesson: length counts the characters, and [i] reads one character.
String Interpolation
String interpolation = putting a value inside a string.
$name= put a variable's value here.${expression}= work out an expression, then put its value here.
$ and ${}
void main() {
var name = 'Ravi';
var maths = 88;
var science = 91;
print('Hello, $name!');
print('Total: ${maths + science}');
print('Name in capitals: ${name.toUpperCase()}');
print('Price: \$5');
}
$name.toUpperCase()would NOT work. Dart would putnamein, then print.toUpperCase()as text. Use${...}for anything more than a plain name.\$prints a real dollar sign.
Simple lesson: use $name for a plain variable and ${...} for anything more.
Concatenation
Concatenation = joining strings end to end.
+joins two strings:'Green' + ' Valley'.- Adjacent string literals = two literals written side by side are joined automatically.
Joining strings
void main() {
var first = 'Green';
var full = first + ' ' + 'Valley';
print(full);
var notice = 'School will close early today '
'because of the rain.';
print(notice);
var marks = 92;
print('Marks: ' + marks.toString());
}
+ only joins Strings. A number needs toString(), or better, interpolation: 'Marks: $marks'.
Simple lesson: prefer interpolation, use + for short joins, and split long text into adjacent literals.
String Comparison
=== are the two strings exactly the same? Capital letters matter.compareTo()= which comes first in dictionary order? Gives-1,0or1.
Comparing strings
void main() {
print('Asha' == 'Asha');
print('Asha' == 'asha');
print('apple'.compareTo('banana'));
print('mango'.compareTo('apple'));
print('kiwi'.compareTo('kiwi'));
print('asha'.toLowerCase() == 'ASHA'.toLowerCase());
}
To compare without caring about case, change both to lower case first.
Simple lesson: == checks exact equality, and compareTo gives dictionary order.
Searching Strings
| Method | Question |
|---|---|
contains(x) | is x anywhere inside? |
startsWith(x) | does it begin with x? |
endsWith(x) | does it end with x? |
indexOf(x) | where is the first x? -1 if missing |
lastIndexOf(x) | where is the last x? |
Searching inside text
void main() {
var email = 'asha.k@greenvalley.edu';
print(email.contains('@'));
print(email.startsWith('asha'));
print(email.endsWith('.edu'));
print(email.indexOf('@'));
print(email.lastIndexOf('.'));
print(email.indexOf('#'));
}
Simple lesson: contains, startsWith and endsWith say yes or no, and indexOf says where.
Extracting Text
substring(start, end) = the characters from start up to (not including) end.
Cut the user name out of an email
Accessing Characters
text[i] gives the character at index i, as a one-letter String.
Simple lesson: substring cuts out a piece by index, and [i] reads one character.
Modifying Strings
Strings never change. These methods give back a new string:
| Method | What it gives |
|---|---|
replaceAll(a, b) | every a changed to b |
replaceFirst(a, b) | only the first a changed |
replaceRange(start, end, x) | the part from start to end replaced by x |
padLeft(n, c) | adds c on the left until the length is n |
padRight(n, c) | adds c on the right until the length is n |
Replacing and padding
void main() {
var notice = 'Holiday on Monday. Monday is a holiday.';
print(notice.replaceAll('Monday', 'Friday'));
print(notice.replaceFirst('Monday', 'Friday'));
print('9876543210'.replaceRange(2, 8, '******'));
print('7'.padLeft(3, '0'));
print('Maths'.padRight(10, '.') + '92');
print('Science'.padRight(10, '.') + '85');
}
padLeft(3, '0') turns roll number 7 into 007. padRight lines up a report card.
Simple lesson: replaceAll swaps text, and padLeft and padRight make text a fixed width.
Case Conversion and Whitespace
toUpperCase()/toLowerCase()= all capitals, or all small letters.trim()= removes spaces at both ends.trimLeft()/trimRight()= only at the left, or only at the right.
Cleaning up a typed name
void main() {
var typed = ' aSHa ';
print('[${typed.trim()}]');
print('[${typed.trimLeft()}]');
print('[${typed.trimRight()}]');
var clean = typed.trim().toLowerCase();
print(clean);
print(clean[0].toUpperCase() + clean.substring(1));
}
The brackets show where the spaces are. The last line makes "Asha" with a capital first letter.
Simple lesson: trim() removes extra spaces, and the case methods fix capital letters.
Splitting and Joining
split(separator)= cuts a string into a List of pieces.join(separator)= the opposite, on a list: glues the pieces into one string.
From text to a list, and back
void main() {
var csv = 'Asha,Ravi,Priya,Kiran';
var names = csv.split(',');
print(names);
print(names.length);
print(names.join(' | '));
print('Hello'.split(''));
var words = 'Dart is fun'.split(' ');
print(words.reversed.join(' '));
}
split('') cuts between every character.
String Conversion
toString() turns any value into text (see Data Types): 92.toString() gives '92'.
Simple lesson: split turns text into a list, and join turns a list into text.
StringBuffer
StringBuffer Fundamentals
StringBuffer = a tool for building a long string piece by piece.
Joining with + in a loop makes a brand new string every round. A StringBuffer keeps adding to one place, which is faster.
StringBuffer Operations
| Method | What it does |
|---|---|
write(x) | adds x |
writeln(x) | adds x and a new line |
writeAll(list, sep) | adds every item, with sep between |
clear() | empties the buffer |
toString() | gives the finished string |
Building a report card
void main() {
var marks = {'Maths': 92, 'Science': 85, 'English': 78};
var report = StringBuffer();
report.writeln('REPORT CARD');
report.writeln('-----------');
marks.forEach((subject, mark) {
report.write(subject.padRight(10));
report.writeln(mark);
});
report.write('Subjects: ');
report.writeAll(marks.keys, ', ');
print(report.toString());
print('Characters: ${report.length}');
}
Simple lesson: use a StringBuffer to build long text, then call toString() once at the end.
Runes and Unicode
Unicode Characters and Emoji
Unicode = a world-wide list that gives every character a number: A is 65, अ is 2309, 😀 is 128512.
- Dart strings store text as UTF-16 units.
- Most characters use one unit.
- Many emoji use two units, so
lengthcounts them as 2.
runes
Rune = one Unicode character code.
Emoji, length and runes
void main() {
var smile = '😀';
print(smile.length);
print(smile.runes.length);
print(smile.runes.first);
print('नमस्ते'.length);
print(String.fromCharCode(65));
print(String.fromCharCodes([72, 105]));
print('\u{1F44D} Well done!');
}
runescounts real characters, so😀is 1 rune.String.fromCharCode(n)= turns a character code into a string.\u{...}= writes a character by its Unicode number.
Never cut a string with substring in the middle of an emoji. Half an emoji shows up as a broken box.
For text with emoji, the characters package handles real letters safely (see Libraries).
Easy way to remember
- Find:
contains,indexOf. Cut:substring,split. - Change:
replaceAll,toUpperCase,trim,padLeft. - Build: interpolation for short text, StringBuffer for long text.
Simple lesson: length counts UTF-16 units, and runes counts real characters.
TL;DR
String = text in quotes. Multi-line:
'''...'''. Raw:r'...'.- Never changes. Methods give a new string.
- Interpolation:
$nameand${expression}. Join:+, or adjacent literals. Compare:
==(exact),compareTo(-1,0,1).- Search:
contains,startsWith,endsWith,indexOf,lastIndexOf.
- Search:
Cut and change:
substring,[i],replaceAll,replaceFirst,replaceRange,padLeft,padRight.- Clean:
toUpperCase,toLowerCase,trim. Split and join:split,join.
- Clean:
StringBuffer =
write,writeln,writeAll,clear,toString.- Unicode:
runes,codeUnits,String.fromCharCode,\u{...}.
- Unicode:
Common mistakes
| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
'$name.length' | $ takes the whole expression | Use ${name.length} | It prints the name, then .length. |
name.toUpperCase(); alone | It changes name | Strings never change | Nothing happens. Store the result. |
'Total: ' + 92 | + joins anything | + needs two Strings | A type error. |
substring(1, 3) gives 3 characters | The end index is included | The end is NOT included | One character too few. |
'Asha' == 'asha' is true | Case does not matter | == is exact | false. Compare lower case versions. |
Building text with + in a long loop | It is just as fast | It makes many copies | Slow code. Use a StringBuffer. |
Counting emoji with length | One emoji = 1 | Many emoji are 2 UTF-16 units | Wrong counts. Use runes. |
Check Yourself
Exercises
What to Remember
- A string is text in quotes. It never changes, so every method gives a new string.
- Use
$nameand${expression}to put values inside text. contains,indexOfandsubstringfind and cut text.replaceAll,trim,toUpperCase,splitandjoinchange and reshape text.- Build long text with StringBuffer, and use
runesto count real characters.
Next: Date and Time. You will learn to work with dates, times and durations, like exam days and homework deadlines.