44
55{{quote {author: "Jamie Zawinski", chapter: true}
66
7- Some people, when confronted with a
8- problem, think ‘I know, I'll use regular expressions.’ Now they have
9- two problems.
7+ Some people, when confronted with a problem, think ‘I know, I'll use
8+ regular expressions.’ Now they have two problems.
109
1110quote}}
1211
2423
2524{{index "Zawinski, Jamie", evolution, adoption, integration}}
2625
27- Programming
28- ((tool))s and techniques survive and spread in a chaotic, evolutionary
29- way. It's not always the pretty or brilliant ones that win but rather
30- the ones that function well enough within the right niche—for example,
31- by being integrated with another successful piece of technology.
26+ Programming ((tool))s and techniques survive and spread in a chaotic,
27+ evolutionary way. It's not always the pretty or brilliant ones that
28+ win but rather the ones that function well enough within the right
29+ niche—for example, by being integrated with another successful piece
30+ of technology.
3231
3332{{index "domain-specific language"}}
3433
@@ -57,8 +56,8 @@ written as a literal value by enclosing the pattern in forward slash
5756(` / ` ) characters.
5857
5958```
60- var re1 = new RegExp("abc");
61- var re2 = /abc/;
59+ let re1 = new RegExp("abc");
60+ let re2 = /abc/;
6261```
6362
6463Both of these regular expression objects represent the same
@@ -84,7 +83,7 @@ expressions and must be preceded by a backslash if they are meant to
8483represent the character itself.
8584
8685```
87- var eighteenPlus = /eighteen\+/;
86+ let eighteenPlus = /eighteen\+/;
8887```
8988
9089Knowing precisely what characters to backslash-escape when writing
@@ -121,10 +120,9 @@ start), `test` will return `true`.
121120
122121{{index "regular expression", "indexOf method"}}
123122
124- Finding out whether a
125- string contains _ abc_ could just as well be done with a call to
126- ` indexOf ` . Regular expressions allow us to go beyond that and express
127- more complicated ((pattern))s.
123+ Finding out whether a string contains _ abc_ could just as well be done
124+ with a call to ` indexOf ` . Regular expressions allow us to express more
125+ complicated ((pattern))s.
128126
129127Say we want to match any ((number)). In a regular expression, putting
130128a ((set)) of characters between square brackets makes that part of the
@@ -156,22 +154,21 @@ same thing as `[0-9]`.
156154
157155{{index "newline character"}}
158156
159- [ cols="1,5"]
160- |====
161- |` \d ` |Any ((digit)) character
162- |` \w ` |An alphanumeric character (“((word character))”)
163- |` \s ` |Any ((whitespace)) character (space, tab, newline, and similar)
164- |` \D ` |A character that is _ not_ a digit
165- |` \W ` |A nonalphanumeric character
166- |` \S ` |A nonwhitespace character
167- |` . ` |Any character except for newline
168- |====
157+ {{table {cols: [ 1, 5] }}}
158+
159+ ` \d ` | Any ((digit)) character
160+ ` \w ` | An alphanumeric character (“((word character))”)
161+ ` \s ` | Any ((whitespace)) character (space, tab, newline, and similar)
162+ ` \D ` | A character that is _ not_ a digit
163+ ` \W ` | A nonalphanumeric character
164+ ` \S ` | A nonwhitespace character
165+ ` . ` | Any character except for newline
169166
170167So you could match a ((date)) and ((time)) format like 30-01-2003
17116815:20 with the following expression:
172169
173170```
174- var dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/;
171+ let dateTime = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/;
175172console.log(dateTime.test("30-01-2003 15:20"));
176173// → true
177174console.log(dateTime.test("30-jan-2003 15:20"));
@@ -203,7 +200,7 @@ character _except_ the ones in the set—you can write a caret (`^`)
203200character after the opening bracket.
204201
205202```
206- var notBinary = /[^01]/;
203+ let notBinary = /[^01]/;
207204console.log(notBinary.test("1100100010100110"));
208205// → false
209206console.log(notBinary.test("1100100010200110"));
@@ -251,7 +248,7 @@ occur zero or one time. In the following example, the _u_ character
251248is allowed to occur, but the pattern also matches when it is missing.
252249
253250```
254- var neighbor = /neighbou?r/;
251+ let neighbor = /neighbou?r/;
255252console.log(neighbor.test("neighbour"));
256253// → true
257254console.log(neighbor.test("neighbor"));
@@ -272,7 +269,7 @@ allows both single- and double-((digit)) days, months, and hours. It
272269is also slightly more readable.
273270
274271```
275- var dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/;
272+ let dateTime = /\d{1,2}-\d{1,2}-\d{4} \d{1,2}:\d{2}/;
276273console.log(dateTime.test("30-1-2003 8:45"));
277274// → true
278275```
@@ -292,7 +289,7 @@ as a single element as far as the operators following it are
292289concerned.
293290
294291```
295- var cartoonCrying = /boo+(hoo+)+/i;
292+ let cartoonCrying = /boo+(hoo+)+/i;
296293console.log(cartoonCrying.test("Boohoooohoohooo"));
297294// → true
298295```
@@ -322,7 +319,7 @@ match was found and return an object with information about the match
322319otherwise.
323320
324321```
325- var match = /\d+/.exec("one two 100");
322+ let match = /\d+/.exec("one two 100");
326323console.log(match);
327324// → ["100"]
328325console.log(match.index);
@@ -358,7 +355,7 @@ matched by the first group (the one whose opening parenthesis comes
358355first in the expression), then the second group, and so on.
359356
360357```
361- var quotedText = /'([^']*)'/;
358+ let quotedText = /'([^']*)'/;
362359console.log(quotedText.exec("she said 'hello'"));
363360// → ["'hello'", "hello"]
364361```
@@ -462,8 +459,8 @@ object from a string.
462459
463460```
464461function findDate(string) {
465- var dateTime = /(\d{1,2})-(\d{1,2})-(\d{4})/;
466- var match = dateTime.exec(string);
462+ let dateTime = /(\d{1,2})-(\d{1,2})-(\d{4})/;
463+ let match = dateTime.exec(string);
467464 return new Date(Number(match[3]),
468465 Number(match[2]) - 1,
469466 Number(match[1]));
@@ -528,7 +525,7 @@ there is a nicer way. The ((pipe character)) (`|`) denotes a
528525right. So I can say this:
529526
530527```
531- var animalCount = /\b\d+ (pig|cow|chicken)s?\b/;
528+ let animalCount = /\b\d+ (pig|cow|chicken)s?\b/;
532529console.log(animalCount.test("15 pigs"));
533530// → true
534531console.log(animalCount.test("15 pigchickens"));
@@ -742,7 +739,7 @@ arguments, and its return value will be inserted into the new string.
742739Here's a simple example:
743740
744741```
745- var s = "the cia and fbi";
742+ let s = "the cia and fbi";
746743console.log(s.replace(/\b(fbi|cia)\b/g, function(str) {
747744 return str.toUpperCase();
748745}));
@@ -752,7 +749,7 @@ console.log(s.replace(/\b(fbi|cia)\b/g, function(str) {
752749And here's a more interesting one:
753750
754751```
755- var stock = "1 lemon, 2 cabbages, and 101 eggs";
752+ let stock = "1 lemon, 2 cabbages, and 101 eggs";
756753function minusOne(match, amount, unit) {
757754 amount = Number(amount) - 1;
758755 if (amount == 1) // only one left, remove the 's'
@@ -858,9 +855,9 @@ But you can build up a string and use the `RegExp` ((constructor)) on
858855that. Here's an example:
859856
860857```
861- var name = "harry";
862- var text = "Harry is a suspicious character.";
863- var regexp = new RegExp("\\b(" + name + ")\\b", "gi");
858+ let name = "harry";
859+ let text = "Harry is a suspicious character.";
860+ let regexp = new RegExp("\\b(" + name + ")\\b", "gi");
864861console.log(text.replace(regexp, "_$1_"));
865862// → _Harry_ is a suspicious character.
866863```
@@ -887,10 +884,10 @@ have a special meaning. But escaping everything that's not
887884alphanumeric or ((whitespace)) is safe.
888885
889886```
890- var name = "dea+hl[]rd";
891- var text = "This dea+hl[]rd guy is super annoying.";
892- var escaped = name.replace(/[^\w\s]/g, "\\$&");
893- var regexp = new RegExp("\\b(" + escaped + ")\\b", "gi");
887+ let name = "dea+hl[]rd";
888+ let text = "This dea+hl[]rd guy is super annoying.";
889+ let escaped = name.replace(/[^\w\s]/g, "\\$&");
890+ let regexp = new RegExp("\\b(" + escaped + ")\\b", "gi");
894891console.log(text.replace(regexp, "_$1_"));
895892// → This _dea+hl[]rd_ guy is super annoying.
896893```
@@ -942,9 +939,9 @@ would have been to just allow an extra argument to be passed to
942939regular expression interface.
943940
944941```
945- var pattern = /y/g;
942+ let pattern = /y/g;
946943pattern.lastIndex = 3;
947- var match = pattern.exec("xyzzy");
944+ let match = pattern.exec("xyzzy");
948945console.log(match.index);
949946// → 4
950947console.log(pattern.lastIndex);
@@ -967,7 +964,7 @@ cause problems. Your regular expression might be accidentally starting
967964at an index that was left over from a previous call.
968965
969966```
970- var digit = /\d/g;
967+ let digit = /\d/g;
971968console.log(digit.exec("here it is: 1"));
972969// → ["1"]
973970console.log(digit.exec("and now: 1"));
@@ -1003,9 +1000,9 @@ that gives us access to the match object in the loop body, by using
10031000` lastIndex ` and ` exec ` .
10041001
10051002```
1006- var input = "A string with 3 numbers in it... 42 and 88.";
1007- var number = /\b(\d+)\b/g;
1008- var match;
1003+ let input = "A string with 3 numbers in it... 42 and 88.";
1004+ let number = /\b(\d+)\b/g;
1005+ let match;
10091006while (match = number.exec(input))
10101007 console.log("Found", match[1], "at", match.index);
10111008// → Found 3 at 14
@@ -1086,11 +1083,11 @@ in a way that allows both `"\n"` and `"\r\n"` between lines.
10861083```
10871084function parseINI(string) {
10881085 // Start with an object to hold the top-level fields
1089- var currentSection = {name: null, fields: []};
1090- var categories = [currentSection];
1086+ let currentSection = {name: null, fields: []};
1087+ let categories = [currentSection];
10911088
10921089 string.split(/\r?\n/).forEach(function(line) {
1093- var match;
1090+ let match;
10941091 if (/^\s*(;.*)?$/.test(line)) {
10951092 return;
10961093 } else if (match = line.match(/^\[(.*)\]$/)) {
@@ -1183,27 +1180,26 @@ unfortunately looks like they won't be realized in the near ((future)).
11831180Regular expressions are objects that represent patterns in strings.
11841181They use their own syntax to express these patterns.
11851182
1186- [ cols="1,5"]
1187- |====
1188- |` /abc/ ` |A sequence of characters
1189- |` /[abc]/ ` |Any character from a set of characters
1190- |` /[^abc]/ ` |Any character _ not_ in a set of characters
1191- |` /[0-9]/ ` |Any character in a range of characters
1192- |` /x+/ ` |One or more occurrences of the pattern ` x `
1193- |` /x+?/ ` |One or more occurrences, nongreedy
1194- |` /x*/ ` |Zero or more occurrences
1195- |` /x?/ ` |Zero or one occurrence
1196- |` /x{2,4}/ ` |Between two and four occurrences
1197- |` /(abc)/ ` |A group
1198- |_ /a{brvbar}b{brvbar}c/_ |Any one of several patterns
1199- |` /\d/ ` |Any digit character
1200- |` /\w/ ` |An alphanumeric character (“word character”)
1201- |` /\s/ ` |Any whitespace character
1202- |` /./ ` |Any character except newlines
1203- |` /\b/ ` |A word boundary
1204- |` /^/ ` |Start of input
1205- |` /$/ ` |End of input
1206- |====
1183+ {{table {cols: [ 1, 5] }}}
1184+
1185+ ` /abc/ ` | A sequence of characters
1186+ ` /[abc]/ ` | Any character from a set of characters
1187+ ` /[^abc]/ ` | Any character _ not_ in a set of characters
1188+ ` /[0-9]/ ` | Any character in a range of characters
1189+ ` /x+/ ` | One or more occurrences of the pattern ` x `
1190+ ` /x+?/ ` | One or more occurrences, nongreedy
1191+ ` /x*/ ` | Zero or more occurrences
1192+ ` /x?/ ` | Zero or one occurrence
1193+ ` /x{2,4}/ ` | Between two and four occurrences
1194+ ` /(abc)/ ` | A group
1195+ ` /a|b|c/ ` | Any one of several patterns
1196+ ` /\d/ ` | Any digit character
1197+ ` /\w/ ` | An alphanumeric character (“word character”)
1198+ ` /\s/ ` | Any whitespace character
1199+ ` /./ ` | Any character except newlines
1200+ ` /\b/ ` | A word boundary
1201+ ` /^/ ` | Start of input
1202+ ` /$/ ` | End of input
12071203
12081204A regular expression has a method ` test ` to test whether a given
12091205string matches it. It also has an ` exec ` method that, when a match is
@@ -1341,7 +1337,7 @@ does the proper replacement.
13411337
13421338{{if interactive
13431339``` {test: no}
1344- var text = "'I'm the cook,' he said, 'it's my job.'";
1340+ let text = "'I'm the cook,' he said, 'it's my job.'";
13451341// Change this call.
13461342console.log(text.replace(/A/g, "B"));
13471343// → "I'm the cook," he said, "it's my job."
@@ -1388,7 +1384,7 @@ are valid JavaScript numbers, but a lone dot _isn't_.
13881384{{if interactive
13891385``` {test: no}
13901386// Fill in this regular expression.
1391- var number = /^...$/;
1387+ let number = /^...$/;
13921388
13931389// Tests:
13941390["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4",
0 commit comments