Chapter 10: Chapter 10. Wrangling regular expressions
The chapter introduction explains why regular expressions are valuable for concise string processing in JavaScript and identifies common uses.
After this chapter you will be able to
- Value of regular expressions. Explain why regular expressions belong in a JavaScript developer’s toolkit: some problems are difficult to solve elegantly without them, and a suitable expression can replace much longer code.
- Concise string-format validation. Explain why the section favors a regular expression for checking a nine-digit ZIP code over explicit character checks, while distinguishing shorter code from fewer runtime comparisons.
- Regular expressions as patterns. Explain that a regular expression expresses a pattern for matching text, built from terms and operators.
- Literal and constructor creation. Distinguish a regex literal from a RegExp constructor call, including when each is preferred and why string-based patterns can require doubled backslashes.
- Regex flags and placement. Describe what the five flags in this section change and where flags go in literal and constructor forms.
- Literal and character-class matches. Explain how adjacent literal characters match a sequence, while a bracketed character class matches one character from a set, its negation, or a range.
- Repetition counts and greediness. Describe what ?, +, *, and brace counts allow after a term, and distinguish greedy from nongreedy repetition.
- Grouping and alternative patterns. Explain how parentheses make a repetition operator apply to a whole group of terms, and how | expresses alternatives.
- Captured-text backreferences. Explain how a numbered backreference matches the text captured earlier rather than another arbitrary member of the same character class.
- Compilation and execution phases. Distinguish compilation, when JavaScript parses a newly created regular expression into an internal representation, from execution, when the compiled expression matches a string.
- Reusable compiled expressions. Justify creating and storing a regular expression once when it will be used repeatedly, rather than relying on browser caching or repeatedly creating the same expression.
- Runtime constructor compilation. Explain why a class name supplied at runtime calls for building a string and compiling it with new RegExp() rather than writing a fixed regex literal.
- Value of captured matches. Explain the difference between determining whether a string matches a pattern and capturing what was matched, and why the latter can be useful.
- Simple capture result structure. Explain how the example obtains the value from translateY(15px): check that a transform property exists, then use a regular-expression match whose parenthesized capture places 15px at index 1 of the result.
- Local and global match results. Distinguish what `String.match` returns with a local regular expression versus one with the `g` flag.
- Captures across global matches. Explain how repeated calls to a global regular expression’s `exec` method provide captures for successive matches.
- Backreferences within a match. Explain how \1 refers to the first capture within a regular expression and how this lets a pattern match a closing HTML tag with the same name as its opening tag.
- Captures in replacement strings. Distinguish capture references in a replace method’s replacement string from those within a regular expression, and explain how $1 inserts the first captured value.
- Grouping without extra captures. Explain how `(?:...)` groups part of a regular expression without capturing it, using the repeated `ninja-` prefix before `sword` as an example.
- Function replacement callback behavior. Explain when String.replace invokes a replacement function, what information it receives, and how its return value is used.
- Replace as string traversal. Describe how the query-string example uses replace to collect key-value pairs rather than to use its replaced string.
- Across newline matching patterns. Describe how /[\S\s]*/ and /(?:.|\s)*/ each match across newlines, and why the section favors the first.
- Unicode-inclusive character class. Explain why an alphanumeric match may need to include characters beyond English ASCII, and describe the section’s example of combining \w with a range starting at U+0080.
- Escaped selector character matching. Explain why a selector engine must accommodate escaped characters in element IDs and describe the expression’s two alternatives: a sequence of word characters or a backslash followed by any character. State that this does not fully support all escape characters.
Section by section
Introduction
The chapter introduction explains why regular expressions are valuable for concise string processing in JavaScript and identifies common uses.
- Value of regular expressions: Explain why regular expressions belong in a JavaScript developer’s toolkit: some problems are difficult to solve elegantly without them, and a suitable expression can replace much longer code.
Why it matters: This explains why the chapter treats regular expressions as a practical tool rather than an optional curiosity. - Common string processing uses: Describe how regular expressions help take apart strings and find information, giving examples of the JavaScript tasks named in the introduction.
Why it matters: These examples connect the chapter’s motivation to recognizable JavaScript tasks.
Key terms: regular expressions, input validation, CSS selector expression
10.1 Why regular expressions rock
Uses ZIP-code validation to show why regular expressions can express a string-format check more concisely than character-by-character code.
- Concise string-format validation: Explain why the section favors a regular expression for checking a nine-digit ZIP code over explicit character checks, while distinguishing shorter code from fewer runtime comparisons.
Why it matters: This example shows the practical appeal of regular expressions before getting into their syntax.
Key terms: regular expressions, ZIP code, decimal digit
10.1 Do you know?
This section poses three self-check questions about regular expressions without explaining their answers.
10.2 A regular expression refresher
This section introduces a brief, nonexhaustive refresher on regular expressions and points readers to books for more detail.
10.2.1 Regular expressions explained
This section defines regular expressions as text-matching patterns and explains how JavaScript creates them and applies flags.
- Regular expressions as patterns: Explain that a regular expression expresses a pattern for matching text, built from terms and operators.
Why it matters: This gives you the basic idea behind the syntax used throughout the chapter. - Literal and constructor creation: Distinguish a regex literal from a RegExp constructor call, including when each is preferred and why string-based patterns can require doubled backslashes.
Why it matters: Choosing the appropriate form makes patterns easier to write, especially when they contain backslashes. - Regex flags and placement: Describe what the five flags in this section change and where flags go in literal and constructor forms.
Why it matters: Flags explain why the same pattern can produce different matching behavior.
Key terms: regular expression, pattern, terms, operators, regular expression literal, RegExp, constructor, backslash, flags, i
10.2.2 Terms and operators
This section explains how regular-expression terms and operators combine to match literal text, character choices, positions, repetitions, alternatives, and previously captured text.
- Literal and character-class matches: Explain how adjacent literal characters match a sequence, while a bracketed character class matches one character from a set, its negation, or a range.
Why it matters: These are the basic building blocks for saying which characters a pattern accepts. - Escapes and string anchors: Distinguish escaping a special character for a literal match from using ^ and $ to require a match at the beginning or end of a string.
Why it matters: Escapes and anchors let a pattern distinguish literal punctuation from a required match position. - Repetition counts and greediness: Describe what ?, +, *, and brace counts allow after a term, and distinguish greedy from nongreedy repetition.
Why it matters: Repetition counts and greediness determine both whether a pattern matches and how much text it consumes. - Predefined character-class terms: Explain why regex syntax provides predefined terms for control characters and commonly used sets such as digits or whitespace.
Why it matters: Predefined terms make common kinds of character matching easier to express. - Grouping and alternative patterns: Explain how parentheses make a repetition operator apply to a whole group of terms, and how | expresses alternatives.
Why it matters: Grouping and alternatives let a pattern express repeated sequences and different acceptable matches. - Captured-text backreferences: Explain how a numbered backreference matches the text captured earlier rather than another arbitrary member of the same character class.
Why it matters: Backreferences let a pattern require later text to agree with text it matched earlier.
Key terms: literal, character class operator, set operator, range, escaping, backslash, anchor, ^, $, repetition operators
10.3 Compiling regular expressions
This section explains when JavaScript compiles regular expressions, why reusing a compiled expression can improve performance, and how to construct one from a runtime string.
- Compilation and execution phases: Distinguish compilation, when JavaScript parses a newly created regular expression into an internal representation, from execution, when the compiled expression matches a string.
Why it matters: The distinction explains why creating an expression repeatedly can add work beyond matching. - Reusable compiled expressions: Justify creating and storing a regular expression once when it will be used repeatedly, rather than relying on browser caching or repeatedly creating the same expression.
Why it matters: Reusing one expression can avoid repeated preparation work when matching many times. - Runtime constructor compilation: Explain why a class name supplied at runtime calls for building a string and compiling it with new RegExp() rather than writing a fixed regex literal.
Why it matters: The constructor lets a program make a reusable pattern from a value it receives only while running. - Class matching pattern details: Describe how the example matches a complete class name within a space-delimited class string, why the constructor string double-escapes the whitespace term, and how it checks elements.
Why it matters: The boundaries keep the search focused on a class name in a list, while correct escaping preserves the intended regex term.
Key terms: compilation, execution, precompiling, regex literal, regular expression object, new RegExp(), className, whitespace character, double-escape, test method
10.4 Capturing matching segments
This section explains why capturing what a regular expression matched can be more useful than merely checking whether a match exists.
- Value of captured matches: Explain the difference between determining whether a string matches a pattern and capturing what was matched, and why the latter can be useful.
Why it matters: Capturing a match lets you use the text you found, rather than only knowing that a match occurred.
Key terms: regular expressions, capture, matches, pattern
10.4.1 Performing simple captures
Shows how to extract a value embedded in a CSS transform string using a regular-expression capture.
- Simple capture result structure: Explain how the example obtains the value from translateY(15px): check that a transform property exists, then use a regular-expression match whose parenthesized capture places 15px at index 1 of the result.
Why it matters: It lets you retrieve an embedded value without confusing the whole match with the captured part.
Key terms: transform property, match method, capture, parentheses
10.4.2 Matching using global expressions
This section contrasts the results of local and global `match` calls and shows how repeated `exec` calls retrieve captures across global matches.
- Local and global match results: Distinguish what `String.match` returns with a local regular expression versus one with the `g` flag.
Why it matters: Choosing the global flag changes what information you get back from `match`. - Captures across global matches: Explain how repeated calls to a global regular expression’s `exec` method provide captures for successive matches.
Why it matters: `exec` lets you obtain captures even when searching for every match.
Key terms: local regular expression, global regular expression, g flag, match, captures, exec, global search, state
10.4.3 Referencing captures
This section shows how captured text can be reused within a regular-expression match or a replacement string, and notes that ordinary grouping parentheses also create captures.
- Backreferences within a match: Explain how \1 refers to the first capture within a regular expression and how this lets a pattern match a closing HTML tag with the same name as its opening tag.
Why it matters: It lets a pattern require repeated text to agree without knowing that text in advance. - Captures in replacement strings: Distinguish capture references in a replace method’s replacement string from those within a regular expression, and explain how $1 inserts the first captured value.
Why it matters: It allows one replacement string to reuse whatever the expression captures at match time. - Parentheses and unintended captures: Explain why parentheses added only for grouping can produce captures the author did not intend.
Why it matters: It explains why a pattern’s captures may include more than its author meant to retain.
Key terms: capture, backreference, \1, replace method, replace string, $1, captures, expression grouping, parentheses
10.4.4 Noncapturing groups
This section shows how noncapturing groups preserve regex grouping without producing unwanted captures.
- Grouping without extra captures: Explain how `(?:...)` groups part of a regular expression without capturing it, using the repeated `ninja-` prefix before `sword` as an example.
Why it matters: You can repeat a grouped pattern while capturing only the part you actually want. - Reasons to avoid needless captures: Justify using noncapturing groups when a grouped result is not needed, while acknowledging the readability trade-off.
Why it matters: Avoiding captures you will not use keeps match results simpler and saves the engine unnecessary work.
Key terms: noncapturing groups, passive subexpression, capture, (?:...), noncapturing (passive) groups, capturing, expression engine
10.5 Replacing using functions
This section explains how a function passed to String.replace can produce a replacement for each regex match or traverse matches to collect data.
- Function replacement callback behavior: Explain when String.replace invokes a replacement function, what information it receives, and how its return value is used.
Why it matters: These callback inputs let you choose a replacement based on the particular match rather than use one fixed string. - Dash to camel case conversion: Trace how the section's global regex and replacement function convert dash-separated words to camel case.
Why it matters: The example shows how a callback uses a capture to calculate a different replacement for each match. - Replace as string traversal: Describe how the query-string example uses replace to collect key-value pairs rather than to use its replaced string.
Why it matters: A replacement callback can also be a compact way to visit matches and gather information without using the replaced string.
Key terms: replace, replacement value, global search, captures, global regex, capture, camel-cased, string traversal, key-value pairs, hash
10.6 Solving common problems with regular expressions
Introduces the upcoming use of regular expressions to solve common JavaScript problems without explaining any solutions yet.
10.6.1 Matching newlines
Explains why a dot does not match newlines in the JavaScript regular expressions described here and shows two patterns that match across them.
- Dot matching and newlines: Explain why a pattern using . does not match through a newline in the section’s example.
Why it matters: This limitation explains why the section needs alternative patterns. - Across newline matching patterns: Describe how /[\S\s]*/ and /(?:.|\s)*/ each match across newlines, and why the section favors the first.
Why it matters: These patterns let a search include line breaks when . alone will not.
Key terms: period (.) term, newline, character class, alternation regex, passive subexpression, /[\S\s]*/, /(?:.|\s)*/
10.6.2 Matching Unicode
This section shows how to extend a regular-expression character class beyond English ASCII characters and explains the tradeoff of matching a broad Unicode range.
- Unicode-inclusive character class: Explain why an alphanumeric match may need to include characters beyond English ASCII, and describe the section’s example of combining \w with a range starting at U+0080.
Why it matters: An English-only character match can exclude text from other languages. - Broad Unicode range tradeoff: Distinguish the broad Unicode match in the example from a character class restricted to a desired range.
Why it matters: Matching more languages does not automatically mean matching only letters.
Key terms: character class, \w, U+0080, Basic Multilingual Plane, Unicode punctuation, range
10.6.3 Matching escaped characters
This section explains why escaped characters matter in CSS selector names and describes a limited regular-expression approach to matching them.
- Escaped selector character matching: Explain why a selector engine must accommodate escaped characters in element IDs and describe the expression’s two alternatives: a sequence of word characters or a backslash followed by any character. State that this does not fully support all escape characters.
Why it matters: Selector code cannot assume that every element ID consists only of word characters.
Key terms: id values, CSS selector engine, escaped characters, word character sequence, backslash
10.7 Summary
10.8 Exercises
Where this is used later
- Untestable browser issues (chapter 14) · Regular expressions involving Unicode
Concepts explained in this chapter
- regex groupingA regular-expression subgroup whose matched text is recorded for later access or reference.
- regular expressionA pattern for matching character sequences in text.
- alternationA regular-expression construct that matches one of several alternative subpatterns.
- character classA regular expression construct in square brackets that matches one character from a specified set or range, optionally negated.
- backreferenceA reference that reuses text previously matched by a capturing group.
- regular expression literalJavaScript source syntax that specifies a regular-expression pattern between slash delimiters, optionally followed by flags.
- quantifierA regular-expression operator that specifies how many times a preceding term may occur.
- replace methodA JavaScript String method that returns a new string with matched text replaced by specified text or text produced by a callback.
- noncapturing groupA regular-expression group that combines subpatterns without recording their matched text as a capture.
- code compilationThe process of translating a program or expression into an internal form suitable for execution.
- exec methodA RegExp method in JavaScript that executes a pattern search and returns the next match result, including captures when available.
- global regular expressionA regular expression with the g flag, enabling successive searches for matches in a string.
- match methodA JavaScript method that searches a string with a regular expression and returns match information.
- metacharacterA character in a regular expression that has a syntactic meaning rather than being matched literally.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
