Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: sdk/lib/core/string.dart

Issue 23480035: Added examples to String docs. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updates based on Mem's comments. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.core; 5 part of dart.core;
6 6
7 /** 7 /**
8 * A class for working with a sequence of characters. 8 * A class for working with a sequence of characters.
9 * 9 *
10 * A string can be either single or multiline. Single line strings are
Lasse Reichstein Nielsen 2013/09/24 08:17:32 "A string literal can be either single- or multili
11 * written using matching single or double quotes, and mutliline strings are
floitsch 2013/09/23 15:12:26 multiline
12 * written using triple quotes. The following are all valid Dart strings:
floitsch 2013/09/23 15:12:26 If you introduce multiline strings here, you shoul
13 *
14 * 'Single quotes';
15 * "Double quotes";
16 * 'Double quotes in "single" quotes';
17 * "Single quotes in 'double' quotes";
18 *
19 * '''A
20 * multiline
21 * string''';
22 *
23 * """
24 * Another
25 * multiline
26 * string""";
Lasse Reichstein Nielsen 2013/09/24 10:31:47 Wrt. a recent mailing list thread, we should docum
floitsch 2013/09/24 10:39:00 See my comment at line 12.
27 *
28 * Strings are immutable. Although you cannot change a string, you can perform
29 * an operation on a string and assign the result to a new string:
floitsch 2013/09/23 15:12:26 To me "operations on strings and assign the result
30 *
31 * var string = 'Dart is fun';
32 * var newString = string.toUpperCase();
floitsch 2013/09/23 15:12:26 Please don't use "toUpperCase" in the leading intr
33 *
34 * You can use the plus (`+`) operator to concatenate strings:
35 *
36 * 'Dart ' + 'is ' + 'fun!'; // 'Dart is fun!'
37 *
38 * You can also use adjacent string literals for concatenation:
39 *
40 * 'Dart ' 'is ' 'fun!'; // 'Dart is fun!'
Lasse Reichstein Nielsen 2013/09/24 08:17:32 This makes it sound like the plus operator is the
41 *
42 * You can use `${}` to interpolate the value of Dart expressions
43 * within strings. The curly braces can be omitted when evaluating identifiers:
floitsch 2013/09/23 15:12:26 nit. (but no need to change the documentation): th
44 *
45 * string = 'dartlang';
46 * '$string has ${string.length} letters'; // 'dartlang has 8 letters'
47 *
10 * A string is represented by a sequence of Unicode UTF-16 code units 48 * A string is represented by a sequence of Unicode UTF-16 code units
11 * accessible through the [codeUnitAt] or the [codeUnits] members. Their 49 * accessible through the [codeUnitAt] or the [codeUnits] members:
12 * string representation is accessible through the index-operator. 50 *
51 * string = 'Dart';
52 * string.codeUnitAt(0); // 68
53 * string.codeUnits; // [68, 97, 114, 116]
54 *
55 * The string representation of code units is accessible through the index
56 * operator:
57 *
58 * string[0]; // 'D'
13 * 59 *
14 * The characters of a string are encoded in UTF-16. Decoding UTF-16, which 60 * The characters of a string are encoded in UTF-16. Decoding UTF-16, which
15 * combines surrogate pairs, yields Unicode code points. Following a similar 61 * combines surrogate pairs, yields Unicode code points. Following a similar
16 * terminology to Go we use the name "rune" for an integer representing a 62 * terminology to Go, we use the name 'rune' for an integer representing a
17 * Unicode code point. The runes of a string are accessible through the [runes] 63 * Unicode code point. Use the [runes] property to get the runes of a string:
18 * getter.
19 * 64 *
20 * Strings are immutable. 65 * string.runes.toList(); // [68, 97, 114, 116]
floitsch 2013/09/23 15:12:26 That example would be more interesting if it was a
21 * 66 *
22 * It is a compile-time error for a class to attempt to extend or implement 67 * For a character outside the Basic Multilingual Plane (plane 0) that is
23 * String. 68 * composed of a surrogate pair, [runes] combines the pair and returns a
69 * single integer. For example, the Unicode character for a
70 * musical G-clef ('𝄞') with rune value 0x1D11E consists of a UTF-16 surrogate
71 * pair: `0xD834` and `0xDD1E`. Using [codeUnits] returns the surrogate pair,
72 * and using `runes` returns their combined value:
floitsch 2013/09/23 15:12:26 If you talk about runes here, no need to have the
24 * 73 *
25 * For concatenating strings efficiently, use the [StringBuffer] class. For 74 * var clef = '\u{1D11E}';
26 * working with regular expressions, use the [RegExp] class. 75 * clef.codeUnits; // [0xD834, 0xDD1E]
76 * clef.runes.toList(); // [0x1D11E]
77 *
78 * Extending or implementing String is a compile-time error.
floitsch 2013/09/23 15:12:26 nit: this was already muddy before, but now that i
79 *
80 * ## Other resources
81 *
82 * See [StringBuffer] to efficiently build a string incrementally. See
83 * [RegExp] to work with regular expressions.
84 *
85 * Also see:
86
87 * * [Dart Cookbook](https://www.dartlang.org/docs/cookbook/#strings)
88 * for String examples and recipes.
89 * * [Dart Up and Running]
90 * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-st rings-and-regular-expressions)
27 */ 91 */
28 abstract class String implements Comparable<String>, Pattern { 92 abstract class String implements Comparable<String>, Pattern {
29 /** 93 /**
30 * Allocates a new String for the specified [charCodes]. 94 * Allocates a new String for the specified [charCodes].
31 * 95 *
32 * The [charCodes] can be UTF-16 code units or runes. If a char-code value is 96 * The [charCodes] can be UTF-16 code units or runes. If a char-code value is
33 * 16-bit it is copied verbatim. If it is greater than 16 bits it is 97 * 16-bit, it is copied verbatim:
34 * decomposed into a surrogate pair. 98 *
99 * new String.fromCharCodes([68]); // 'D'
100 *
101 * If a char-code value is greater than 16-bits, it is decomposed into a
102 * surrogate pair:
103 *
104 * var clef = new String.fromCharCodes([0x1D11E]);
105 * clef.codeUnitAt(0); // 0xD834
106 * clef.codeUnitAt(1); // 0xDD1E
35 */ 107 */
36 external factory String.fromCharCodes(Iterable<int> charCodes); 108 external factory String.fromCharCodes(Iterable<int> charCodes);
37 109
38 /** 110 /**
39 * Allocates a new String for the specified [charCode]. 111 * Allocates a new String for the specified [charCode].
40 * 112 *
41 * The new string contains a single code unit if the [charCode] can be 113 * If the [charCode] can be represented by a single ITF-16 code unit, the new
floitsch 2013/09/23 15:12:26 UTF
42 * represented by a single UTF-16 code unit. Otherwise the [length] is 2 and 114 * string contains a single code unit. Otherwise, the [length] is 2 and
43 * the code units form a surrogate pair. 115 * the code units form a surrogate pair. See documentation for
116 * [fromCharCodes].
44 * 117 *
45 * It is allowed (though generally discouraged) to create a String with only 118 * You should avoid creating a String with half of a surrogate pair.
floitsch 2013/09/23 15:12:26 That doesn't feel like what I wanted to say. Let's
Kathy Walrath 2013/09/25 18:47:38 I'd like to avoid the "It is". Also, why would you
46 * one half of a surrogate pair.
47 */ 119 */
48 factory String.fromCharCode(int charCode) { 120 factory String.fromCharCode(int charCode) {
49 List<int> charCodes = new List<int>.filled(1, charCode); 121 List<int> charCodes = new List<int>.filled(1, charCode);
50 return new String.fromCharCodes(charCodes); 122 return new String.fromCharCodes(charCodes);
51 } 123 }
52 124
53 /** 125 /**
54 * Gets the character (as a single-code-unit [String]) at the given [index]. 126 * Gets the character (as a single-code-unit [String]) at the given [index].
55 * 127 *
56 * The returned string represents exactly one UTF-16 code unit which may be 128 * The returned string represents exactly one UTF-16 code unit, which may be
57 * half of a surrogate pair. For example the Unicode character for a 129 * half of a surrogate pair. A single member of a surrogate pair is an
58 * musical G-clef ("𝄞") with rune value 0x1D11E consists of a UTF-16 surrogate 130 * invalid UTF-16 string:
floitsch 2013/09/23 15:12:26 ... UTF-16 string, but valid Dart string:
Lasse Reichstein Nielsen 2013/09/24 08:17:32 ... but not a valid Dart String literal: "\uD800"
floitsch 2013/09/24 09:32:40 Fwiw: we should change that. I filed http://dartbu
59 * pair: `0xD834` and `0xDD1E`. Using the index-operator on this string yields
60 * a String with half of a surrogate pair:
61 * 131 *
62 * var clef = "\u{1D11E}"; 132 * var clef = '\u{1D11E}';
63 * clef.length; // => 2 133 * // These represent invalid UTF-16 strings.
floitsch 2013/09/23 15:12:26 What are "these" ? clef[0].codeUnits is not a stri
64 * clef.runes.first == 0x1D11E; // => true 134 * clef[0].codeUnits; // [0xD834]
65 * clef.runes.length; // => 1 135 * clef[1].codeUnits; // [0xDD1E]
66 * clef.codeUnitAt(0); // => 0xD834
67 * clef.codeUnitAt(1); // => 0xDD1E
68 * // The following strings are halves of a UTF-16 surrogate pair and
69 * // thus invalid UTF-16 strings:
70 * clef[0]; // => a string of length 1 with code-unit value 0xD834.
71 * clef[1]; // => a string of length 1 with code-unit value 0xDD1E.
72 * 136 *
73 * This method is equivalent to 137 * This method is equivalent to
74 * `new String.fromCharCode(this.codeUnitAt(index))`. 138 * `new String.fromCharCode(this.codeUnitAt(index))`.
75 */ 139 */
76 String operator [](int index); 140 String operator [](int index);
77 141
78 /** 142 /**
79 * Returns the 16-bit UTF-16 code unit at the given [index]. 143 * Returns the 16-bit UTF-16 code unit at the given [index].
80 */ 144 */
81 int codeUnitAt(int index); 145 int codeUnitAt(int index);
82 146
83 /** 147 /**
84 * The length of the string. 148 * The length of the string.
85 * 149 *
86 * Returns the number of UTF-16 code units in this string. The number 150 * Returns the number of UTF-16 code units in this string. The number
87 * of [runes] might be less, if the string contains characters outside 151 * of [runes] might be fewer, if the string contains characters outside
88 * the basic multilingual plane (plane 0). 152 * the Basic Multilingual Plane (plane 0). For example:
floitsch 2013/09/23 15:12:26 At some other place you removed the "Example" part
153 *
154 * 'Dart'.length; // 4
155 * 'Dart'.runes.length; // 4
156 *
157 * var clef = '\u{1D11E}';
158 * clef.length; // 2
159 * clef.runes.length; // 1
89 */ 160 */
90 int get length; 161 int get length;
91 162
92 /** 163 /**
93 * Returns whether the two strings are equal. 164 * Returns whether the two strings are equal.
94 * 165 *
95 * This method compares each individual code unit of the strings. 166 * This method compares each individual code unit of the strings.
96 * Equivalently (for strings that are well-formed UTF-16) it compares each 167 * For strings that are well-formed UTF-16, it compares each
floitsch 2013/09/23 15:12:26 This sentence now makes even less sense than befor
97 * individual rune (code point). It does not check for Unicode equivalence. 168 * individual rune (code point). It does not check for Unicode equivalence.
98 * For example the two following strings both represent the string "Amélie" 169 * For example, both the following strings represent the string 'Amélie',
99 * but, due to their different encoding will not return equal. 170 * but due to their different encoding, are not equal:
100 * 171 *
101 * "Am\xe9lie" 172 * 'Am\xe9lie' == 'Ame\u{301}lie'; // false
102 * "Ame\u{301}lie"
103 * 173 *
104 * In the first string the "é" is encoded as a single unicode code unit (also 174 * The first string encodes 'é' as a single unicode code unit (also
105 * a single rune), whereas the second string encodes it as "e" with the 175 * a single rune), whereas the second string encodes it as 'e' with the
106 * combining accent character "◌́". 176 * combining accent character '◌́'.
107 */ 177 */
108 bool operator ==(var other); 178 bool operator ==(var other);
109 179
110 /** 180 /**
111 * Returns whether this string ends with [other]. 181 * Returns true if this string ends with [other]. For example:
floitsch 2013/09/23 15:12:26 ditto. At some other place you removed the "Exampl
182 *
183 * 'Dart'.endsWith('t'); // true
112 */ 184 */
113 bool endsWith(String other); 185 bool endsWith(String other);
114 186
115 /** 187 /**
116 * Returns whether this string starts with a match of [pattern]. 188 * Returns true if this string starts with a match of [pattern].
117 * 189 *
118 * If [index] is provided, instead check if the substring starting 190 * var string = 'Dart';
119 * at that index starts with a match of [pattern]. 191 * string.startsWith('D'); // true
192 * string.startsWith(new RegExp(r'[A-Z][a-z]')); // true
120 * 193 *
121 * It is an error if [index] is negative or greater than [length]. 194 * If [index] is provided, this method checks if the substring starting
195 * at that index starts with a match of [pattern]:
122 * 196 *
123 * A [RegExp] containing "^" will not match if the [index] is greater than 197 * string.startsWith('art', 1); // true
198 * string.startsWith(new RegExp(r'\w{3}')); // true
199 *
200 * An error occurs if [index] is negative or greater than [length].
floitsch 2013/09/23 15:12:26 As said in other CLs. We don't like "An error occu
201 *
202 * A [RegExp] containing '^' does not match if the [index] is greater than
124 * zero. The pattern works on the string as a whole, and does not extract 203 * zero. The pattern works on the string as a whole, and does not extract
125 * a substring starting at [index] first. That is. 204 * a substring starting at [index] first. For example:
126 * "abc".startsWith(new RegExp("^.", 1)) == false 205 *
206 * string.startsWith(new RegExp(r'^art'), 1); // false
207 * string.startsWith(new RegExp(r'art'), 1); // true
127 */ 208 */
128 bool startsWith(Pattern pattern, [int index = 0]); 209 bool startsWith(Pattern pattern, [int index = 0]);
129 210
130 /** 211 /**
131 * Returns the first position of a match of [pattern] in this string, 212 * Returns the position of the first match of [pattern] in this string,
132 * starting at [start] (inclusive). 213 * starting at [start] (inclusive). For example:
floitsch 2013/09/23 15:12:26 ditto ("for example").
133 * 214 *
134 * Returns -1 if a match could not be found. 215 * var string = 'Dartisans';
216 * string.indexOf('art'); // 1
217 * string.indexOf(new RegExp(r'[A-Z][a-z]')); // 0
135 * 218 *
136 * It is an error if start is negative or greater than [length]. 219 * Returns -1 if no match is found:
220 *
221 * string.indexOf(new RegExp(r'dart')); // -1
222 *
223 * An error occurs if [start] is negative or greater than [length].
floitsch 2013/09/23 15:12:26 ditto ("An error occurs").
137 */ 224 */
138 int indexOf(Pattern pattern, [int start]); 225 int indexOf(Pattern pattern, [int start]);
139 226
140 /** 227 /**
141 * Returns the last position of a match [pattern] in this string, searching 228 * Returns the position of the last match [pattern] in this string, searching
142 * backward starting at [start] (inclusive). 229 * backward starting at [start] (inclusive).
143 * 230 *
231 * var string = 'Dartisans';
232 * string.lastIndexOf('a'); // 6
233 * string.lastIndexOf(new RegExp(r'a(r|n)')); // 6
234 *
144 * Returns -1 if [other] could not be found. 235 * Returns -1 if [other] could not be found.
145 * 236 *
146 * It is an error if start is negative or greater than [length]. 237 * string.lastIndexOf(new RegExp(r'DART')); // -1
238 *
239 * In error occurs if start is negative or greater than [length].
floitsch 2013/09/23 15:12:26 ditto. And "An error" not "In error".
Lasse Reichstein Nielsen 2013/09/24 08:17:32 But do rewrite to "It is an error if [start] is ne
147 */ 240 */
148 int lastIndexOf(Pattern pattern, [int start]); 241 int lastIndexOf(Pattern pattern, [int start]);
149 242
150 /** 243 /**
151 * Returns whether this string is empty. 244 * Returns whether this string is empty.
152 */ 245 */
153 bool get isEmpty; 246 bool get isEmpty;
154 247
155 /** 248 /**
156 * Returns whether this string is not empty. 249 * Returns whether this string is not empty.
157 */ 250 */
158 bool get isNotEmpty; 251 bool get isNotEmpty;
159 252
160 /** 253 /**
161 * Creates a new string by concatenating this string with [other]. 254 * Creates a new string by concatenating this string with [other].
162 * 255 *
163 * A sequence of strings can be concatenated by using [Iterable.join]: 256 * 'dart' + 'lang'; // 'dartlang'
164 * 257 *
165 * var strings = ['foo', 'bar', 'geez']; 258 * Use [Iterable.join] to concatenate a sequence of strings:
floitsch 2013/09/23 15:12:26 Should also reference the StringBuffer class.
166 * var concatenated = strings.join(); 259 *
260 * var fruits = ['apple', 'banana', 'orange'];
261 * fruits.join(' : '); // 'apple : banana : orange'
167 */ 262 */
168 String operator +(String other); 263 String operator +(String other);
169 264
170 /** 265 /**
171 * Returns a substring of this string in the given range. 266 * Returns the substring of this string that extends from [startIndex]
172 * [startIndex] is inclusive and [endIndex] is exclusive. 267 * (inclusive) to [endIndex] (exclusive).
floitsch 2013/09/23 15:12:26 "[startIndex](inclusive)" is valid markdown but wo
268 *
269 * var string = 'dartlang';
270 * string.substring(1); // 'artlang'
271 * string.substring(1, 4); // 'art'
173 */ 272 */
174 String substring(int startIndex, [int endIndex]); 273 String substring(int startIndex, [int endIndex]);
175 274
176 /** 275 /**
177 * Removes leading and trailing whitespace from a string. 276 * Removes leading and trailing whitespace from a string.
178 * 277 *
179 * If the string contains leading or trailing whitespace a new string with no 278 * If the string contains leading or trailing whitespace, a new string with no
180 * leading and no trailing whitespace is returned. Otherwise, the string 279 * leading and no trailing whitespace is returned:
181 * itself is returned. 280 *
281 * '\tDart is fun\n'.trim(); // 'Dart is fun'
282 *
283 * Otherwise, the original string itself is returned:
floitsch 2013/09/23 15:12:26 The correct example would verify that the returned
284 *
285 * 'Dart'.trim(); // 'Dart'
182 * 286 *
183 * Whitespace is defined by the Unicode White_Space property (as defined in 287 * Whitespace is defined by the Unicode White_Space property (as defined in
184 * version 6.2 or later) and the BOM character, 0xFEFF. 288 * version 6.2 or later) and the BOM character, 0xFEFF.
185 * 289 *
186 * Here is the list of trimmed characters (following version 6.2): 290 * Here is the list of trimmed characters (following version 6.2):
187 * 291 *
188 * 0009..000D ; White_Space # Cc <control-0009>..<control-000D> 292 * 0009..000D ; White_Space # Cc <control-0009>..<control-000D>
189 * 0020 ; White_Space # Zs SPACE 293 * 0020 ; White_Space # Zs SPACE
190 * 0085 ; White_Space # Cc <control-0085> 294 * 0085 ; White_Space # Cc <control-0085>
191 * 00A0 ; White_Space # Zs NO-BREAK SPACE 295 * 00A0 ; White_Space # Zs NO-BREAK SPACE
192 * 1680 ; White_Space # Zs OGHAM SPACE MARK 296 * 1680 ; White_Space # Zs OGHAM SPACE MARK
193 * 180E ; White_Space # Zs MONGOLIAN VOWEL SEPARATOR 297 * 180E ; White_Space # Zs MONGOLIAN VOWEL SEPARATOR
194 * 2000..200A ; White_Space # Zs EN QUAD..HAIR SPACE 298 * 2000..200A ; White_Space # Zs EN QUAD..HAIR SPACE
195 * 2028 ; White_Space # Zl LINE SEPARATOR 299 * 2028 ; White_Space # Zl LINE SEPARATOR
196 * 2029 ; White_Space # Zp PARAGRAPH SEPARATOR 300 * 2029 ; White_Space # Zp PARAGRAPH SEPARATOR
197 * 202F ; White_Space # Zs NARROW NO-BREAK SPACE 301 * 202F ; White_Space # Zs NARROW NO-BREAK SPACE
198 * 205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE 302 * 205F ; White_Space # Zs MEDIUM MATHEMATICAL SPACE
199 * 3000 ; White_Space # Zs IDEOGRAPHIC SPACE 303 * 3000 ; White_Space # Zs IDEOGRAPHIC SPACE
200 * 304 *
201 * FEFF ; BOM ZERO WIDTH NO_BREAK SPACE 305 * FEFF ; BOM ZERO WIDTH NO_BREAK SPACE
202 */ 306 */
203 String trim(); 307 String trim();
204 308
205 /** 309 /**
206 * Returns whether this string contains a match of [other]. 310 * Returns true if this string contains a match of [other]:
207 * 311 *
208 * If [startIndex] is provided, only matches at or after that index 312 * var string = 'Dart strings';
209 * are considered. 313 * string.contains('D'); // true
314 * string.contains(new RegExp(r'[A-Z]')); // true
210 * 315 *
211 * It is an error if [startIndex] is negative or greater than [length]. 316 * If [startIndex] is provided, this method matches only at or after that
317 * index:
318 *
319 * string.contains('X', 1); // false
320 * string.contains(new RegExp(r'[A-Z]'), 1); // false
321 *
322 * An error occurs if [startIndex] is negative or greater than [length].
floitsch 2013/09/23 15:12:26 ditto ("An error occurs").
212 */ 323 */
213 bool contains(Pattern other, [int startIndex = 0]); 324 bool contains(Pattern other, [int startIndex = 0]);
214 325
215 /** 326 /**
216 * Returns a new string where the first occurence of [from] in this string 327 * Returns a new string in which the first occurence of [from] in this string
217 * is replaced with [to]. 328 * is replaced with [to]. For example:
floitsch 2013/09/23 15:12:26 ditto ("for example").
329 *
330 * '0.0001'.replaceFirst(new RegExp(r'0+'), ''); // '.0001'
floitsch 2013/09/23 15:12:26 bad example. Why the "0+" (and not just "0") ? Wha
218 */ 331 */
219 String replaceFirst(Pattern from, String to); 332 String replaceFirst(Pattern from, String to);
220 333
221 /** 334 /**
222 * Replaces all substrings matching [from] with [replace]. 335 * Replaces all substrings matching [from] with [replace].
223 * 336 *
224 * Returns a new string where the non-overlapping substrings that match 337 * Returns a new string where the non-overlapping substrings that match
225 * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced 338 * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced
226 * by the literal string [replace]. 339 * by the literal string [replace].
227 * 340 *
341 * 'resume'.replaceAll(new RegExp(r'e'), '\u00E9'); // 'résumé'
floitsch 2013/09/23 15:12:26 no need for the \u. Just put "é" there.
Lasse Reichstein Nielsen 2013/09/24 08:17:32 Unless it is to distinguish it from "e\u0301" that
342 *
228 * Notice that the [replace] string is not interpreted. If the replacement 343 * Notice that the [replace] string is not interpreted. If the replacement
229 * depends on the match (for example on a [RegExp]'s capture groups), use 344 * depends on the match (for example on a [RegExp]'s capture groups), use
230 * the [replaceAllMapped] method instead. 345 * the [replaceAllMapped] method instead.
231 */ 346 */
232 String replaceAll(Pattern from, String replace); 347 String replaceAll(Pattern from, String replace);
233 348
234 /** 349 /**
235 * Replace all substrings matching [from] by a string computed from the match. 350 * Replace all substrings matching [from] by a string computed from the match.
236 * 351 *
237 * Returns a new string where the non-overlapping substrings that match 352 * Returns a new string where the non-overlapping substrings that match
238 * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced 353 * [from] (the ones iterated by `from.allMatches(thisString)`) are replaced
239 * by the result of calling [replace] on the corresponding [Match] object. 354 * by the result of calling [replace] on the corresponding [Match] object.
240 * 355 *
241 * This can be used to replace matches with new content that depends on the 356 * This can be used to replace matches with new content that depends on the
242 * match, unlike [replaceAll] where the replacement string is always the same. 357 * match, unlike [replaceAll] where the replacement string is always the same.
243 * 358 *
244 * Example (simplified pig latin): 359 * The [replace] function is called with the [Match] generated
360 * by the pattern, and its result is used as replacement.
361 *
362 * The function defined below converts each word in a string to 'pig latin'
floitsch 2013/09/23 15:12:26 to simplified 'pig latin' ... ?
Lasse Reichstein Nielsen 2013/09/24 08:17:32 Better say "simplified" since real pig-latin is ba
363 * using [replaceAllMapped]:
364 *
245 * pigLatin(String words) => words.replaceAllMapped( 365 * pigLatin(String words) => words.replaceAllMapped(
246 * new RegExp(r"\b(\w*?)([aeiou]\w*)", caseSensitive: false), 366 * new RegExp(r'\b(\w*?)([aeiou]\w*)', caseSensitive: false),
247 * (Match m) => "${m[2]}${m[1]}${m[1].isEmpty ? 'way' : 'ay'}"); 367 * (Match m) => "${m[2]}${m[1]}${m[1].isEmpty ? 'way' : 'ay'}");
248 * 368 *
249 * This would convert each word of a text to "pig-latin", so for example 369 * pigLatin('I have a secret now!'); // 'Iway avehay away ecretsay ownay!'
250 * `pigLatin("I have a secret now!")`
251 * returns
252 * `"Iway avehay away ecretsay ownay!"`
253 */ 370 */
254 String replaceAllMapped(Pattern from, String replace(Match match)); 371 String replaceAllMapped(Pattern from, String replace(Match match));
255 372
256 /** 373 /**
257 * Splits the string around matches of [pattern]. Returns 374 * Splits the string around matches of [pattern]. Returns
258 * a list of substrings. 375 * a list of substrings.
259 * 376 *
260 * Splitting with an empty string pattern (`""`) splits at UTF-16 code unit 377 * Splitting with an empty string pattern (`''`) splits at UTF-16 code unit
261 * boundaries and not at rune boundaries. The following two expressions 378 * boundaries and not at rune boundaries:
Lasse Reichstein Nielsen 2013/09/24 08:17:32 Useful as example because it is a common case, but
262 * are hence equivalent:
263 * 379 *
264 * string.split("") 380 * var string = 'Pub';
265 * string.codeUnits.map((unit) => new String.fromCharCode(unit)) 381 * string.split(''); // ['P', 'u', 'b']
266 * 382 *
267 * Unless it guaranteed that the string is in the basic multilingual plane 383 * string.codeUnits.map((unit) {
384 * return new String.fromCharCode(unit);
385 * }).toList(); // ['P', 'u', 'b']
386 *
387 * // String made up of two code units, but one rune.
388 * string = '\u{1D11E}';
389 * string.split('').length; // 2
Lasse Reichstein Nielsen 2013/09/24 08:17:32 We could define a RunePattern that would always ma
390 *
391 * Unless it is guaranteed that the string is in the basic multilingual plane
268 * (meaning that each code unit represents a rune) it is often better to 392 * (meaning that each code unit represents a rune) it is often better to
269 * map the runes instead: 393 * map the runes instead:
270 * 394 *
271 * string.runes.map((rune) => new String.fromCharCode(rune)) 395 * You should [map] the runes unless you are certain that the string is in
396 * the basic multilingual plane (meaning that each code unit represents a
floitsch 2013/09/23 15:12:26 I guess you wanted to remove the old paragraph.
397 * rune):
398 *
399 * string.runes.map((rune) => new String.fromCharCode(rune));
272 */ 400 */
273 List<String> split(Pattern pattern); 401 List<String> split(Pattern pattern);
274 402
275 /** 403 /**
276 * Splits the string on the [pattern], then converts each part and each match. 404 * Splits the string based on [pattern], converts both the matched and
Kathy Walrath 2013/09/25 18:47:38 This is a pretty long description. How about just:
405 * unmatched parts, and rejoins the parts into a new string.
277 * 406 *
278 * The pattern is used to split the string into parts and separating matches. 407 * The pattern is used to split the string into parts and separating matches.
floitsch 2013/09/23 15:12:26 [pattern]
279 * 408 *
280 * Each match is converted to a string by calling [onMatch]. If [onMatch] 409 * Each match is converted to a string by calling [onMatch]. If [onMatch]
281 * is omitted, the matched string is used. 410 * is omitted, the matched string is used.
282 * 411 *
283 * Each non-matched part is converted by a call to [onNonMatch]. If 412 * Each non-matched part is converted by a call to [onNonMatch]. If
284 * [onNonMatch] is omitted, the non-matching part is used. 413 * [onNonMatch] is omitted, the non-matching part is used.
285 * 414 *
286 * Then all the converted parts are combined into the resulting string. 415 * Then all the converted parts are combined into the resulting string.
416 *
417 * 'Eats SHOOTS leaves'.splitMapJoin((new RegExp(r'SHOOTS')),
418 * onMatch: (m) => '*${m.group(0).toLowerCase()}*',
floitsch 2013/09/23 15:12:26 please don't use toLowerCase/toUpperCase in exampl
419 * onNonMatch: (n) => n.toUpperCase()); // 'EATS *shoots* LEAVES'
287 */ 420 */
288 String splitMapJoin(Pattern pattern, 421 String splitMapJoin(Pattern pattern,
289 {String onMatch(Match match), 422 {String onMatch(Match match),
290 String onNonMatch(String nonMatch)}); 423 String onNonMatch(String nonMatch)});
291 424
292 /** 425 /**
293 * Returns an unmodifiable list of the UTF-16 code units of this string. 426 * Returns an unmodifiable list of the UTF-16 code units of this string.
294 */ 427 */
295 List<int> get codeUnits; 428 List<int> get codeUnits;
296 429
297 /** 430 /**
298 * Returns an iterable of Unicode code-points of this string. 431 * Returns an [Iterable] of Unicode code-points of this string.
299 * 432 *
300 * If the string contains surrogate pairs, they will be combined and returned 433 * If the string contains surrogate pairs, they are combined and returned
301 * as one integer by this iterator. Unmatched surrogate halves are treated 434 * as one integer by this iterator. Unmatched surrogate halves are treated
302 * like valid 16-bit code-units. 435 * like valid 16-bit code-units.
303 */ 436 */
304 Runes get runes; 437 Runes get runes;
305 438
306 /** 439 /**
307 * If this string is not already all lower case, returns a new string 440 * Converts all characters in this string to lower case.
308 * where all characters are made lower case. Returns [:this:] otherwise. 441 * If the string is already in all lower case, this method returns [:this:].
442 *
443 * 'ALPHABET'.toLowerCase(); // 'alphabet'
444 * 'abc'.toLowerCase(); // 'abc'
floitsch 2013/09/23 15:12:26 Please add documentation that this function uses t
309 */ 445 */
310 // TODO(floitsch): document better. (See EcmaScript for description). 446 // TODO(floitsch): document better. (See EcmaScript for description).
311 String toLowerCase(); 447 String toLowerCase();
312 448
313 /** 449 /**
314 * If this string is not already all upper case, returns a new string 450 * Converts all characters in this string to upper case.
315 * where all characters are made upper case. Returns [:this:] otherwise. 451 * If the string is already in all upper case, this method returns [:this:].
452 *
453 * 'alphabet'.toUpperCase(); // 'ALPHABET'
454 * 'ABC'.toUpperCase(); // 'ABC'
floitsch 2013/09/23 15:12:26 ditto. "i".toUpperCase should be "İ" in Turkey. h
316 */ 455 */
317 // TODO(floitsch): document better. (See EcmaScript for description). 456 // TODO(floitsch): document better. (See EcmaScript for description).
318 String toUpperCase(); 457 String toUpperCase();
319 } 458 }
320 459
321 /** 460 /**
322 * The runes (integer Unicode code points) of a [String]. 461 * The runes (integer Unicode code points) of a [String].
323 */ 462 */
324 class Runes extends IterableBase<int> { 463 class Runes extends IterableBase<int> {
325 final String string; 464 final String string;
326 Runes(this.string); 465 Runes(this.string);
327 466
328 RuneIterator get iterator => new RuneIterator(string); 467 RuneIterator get iterator => new RuneIterator(string);
329 468
330 int get last { 469 int get last {
331 if (string.length == 0) { 470 if (string.length == 0) {
332 throw new StateError("No elements."); 471 throw new StateError('No elements.');
floitsch 2013/09/23 15:12:26 why? (not that I care).
333 } 472 }
334 int length = string.length; 473 int length = string.length;
335 int code = string.codeUnitAt(length - 1); 474 int code = string.codeUnitAt(length - 1);
336 if (_isTrailSurrogate(code) && string.length > 1) { 475 if (_isTrailSurrogate(code) && string.length > 1) {
337 int previousCode = string.codeUnitAt(length - 2); 476 int previousCode = string.codeUnitAt(length - 2);
338 if (_isLeadSurrogate(previousCode)) { 477 if (_isLeadSurrogate(previousCode)) {
339 return _combineSurrogatePair(previousCode, code); 478 return _combineSurrogatePair(previousCode, code);
340 } 479 }
341 } 480 }
342 return code; 481 return code;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 throw new RangeError.range(index, 0, string.length); 533 throw new RangeError.range(index, 0, string.length);
395 } 534 }
396 _checkSplitSurrogate(index); 535 _checkSplitSurrogate(index);
397 } 536 }
398 537
399 /** Throw an error if the index is in the middle of a surrogate pair. */ 538 /** Throw an error if the index is in the middle of a surrogate pair. */
400 void _checkSplitSurrogate(int index) { 539 void _checkSplitSurrogate(int index) {
401 if (index > 0 && index < string.length && 540 if (index > 0 && index < string.length &&
402 _isLeadSurrogate(string.codeUnitAt(index - 1)) && 541 _isLeadSurrogate(string.codeUnitAt(index - 1)) &&
403 _isTrailSurrogate(string.codeUnitAt(index))) { 542 _isTrailSurrogate(string.codeUnitAt(index))) {
404 throw new ArgumentError("Index inside surrogate pair: $index"); 543 throw new ArgumentError('Index inside surrogate pair: $index');
405 } 544 }
406 } 545 }
407 546
408 /** 547 /**
409 * Returns the starting position of the current rune in the string. 548 * Returns the starting position of the current rune in the string.
410 * 549 *
411 * Returns null if the [current] rune is null. 550 * Returns null if the [current] rune is null.
412 */ 551 */
413 int get rawIndex => (_position != _nextPosition) ? _position : null; 552 int get rawIndex => (_position != _nextPosition) ? _position : null;
414 553
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 _position = position - 1; 648 _position = position - 1;
510 _currentCodePoint = _combineSurrogatePair(prevCodeUnit, codeUnit); 649 _currentCodePoint = _combineSurrogatePair(prevCodeUnit, codeUnit);
511 return true; 650 return true;
512 } 651 }
513 } 652 }
514 _position = position; 653 _position = position;
515 _currentCodePoint = codeUnit; 654 _currentCodePoint = codeUnit;
516 return true; 655 return true;
517 } 656 }
518 } 657 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698