JavaScript • Collections and Strings

String Manipulation & Regex — Use split/join/trim/replace and regex basics (intro)

Master the essential tools for searching, transforming, and cleaning text data in JavaScript.

JavaScript emblem with code brackets, braces, and a code file.
Inside this lesson 10 sections 5 questions 7 figures

SECTION 1

Historical Context & Motivation

Since the earliest days of computing, programs have needed to work with text. Whether it's a username typed into a login form, a message sent in a chat app, or data pulled from a spreadsheet, strings — sequences of characters — are everywhere. Early programming languages offered only basic operations like reading one character at a time, which made even simple tasks like finding a word in a sentence surprisingly tedious. As software grew more complex, developers needed faster, more powerful ways to search, split, clean, and transform text.

The idea of describing text patterns with a special mini-language led to regular expressions (often shortened to regex). Regex gave programmers a concise way to say things like "find every phone number in this document" or "check if this email address is valid." When Brendan Eich created JavaScript in 1995, he built regex support right into the language alongside handy string methods such as split, replace, and others. These tools remain essential for every JavaScript developer today.

1956 • Regular Expressions Conceived

Mathematician Stephen Kleene formalized regular expressions as a notation for describing patterns in sets of strings, laying the theoretical groundwork.

1968 • Regex in Unix Tools

Ken Thompson embedded regex into the Unix text editor ed, making pattern matching a practical programming tool for the first time.

1995 • JavaScript Is Born

Brendan Eich created JavaScript in ten days at Netscape, including built-in String methods and a RegExp object inspired by Perl's powerful regex engine.

2015 • ES6 Modernizes Strings

ECMAScript 2015 (ES6) introduced template literals, String.prototype.trim was already standard, and new methods like startsWith and includes were added.

The core question this lesson addresses is: How do we efficiently search, clean, split, and reassemble strings in JavaScript? By the end, you'll be comfortable using split, join, trim, replace, and basic regex patterns to handle real-world text tasks.

SECTION 2

Core Principles & Definitions

Before diving into code, let's establish the foundational ideas. In JavaScript, a string is immutable, meaning every method that appears to "change" a string actually returns a brand-new string while the original stays untouched. Understanding this principle prevents a very common bug: calling a method and forgetting to store the result.

1

split(separator)

Breaks a string into an array of substrings wherever the separator appears. Think of slicing a sentence at every space to get individual words.
2

join(separator)

The reverse of split: takes an array and glues all elements into a single string, placing the separator between each element.
3

trim() / trimStart() / trimEnd()

Removes whitespace (spaces, tabs, newlines) from the edges of a string. Essential for cleaning user input from forms.
4

replace(pattern, replacement)

Finds the first match of a pattern and swaps it with the replacement text. Use replaceAll or a regex with the g flag to replace every occurrence.
5

Regular Expressions (Regex)

A mini-language for describing text patterns. Written between forward slashes like /hello/i. Regex can be passed to split, replace, match, and test.
✦

KEY TAKEAWAY

Think of a string like a printed poster — you can't erase a letter on the poster itself, but you can photocopy it with changes. Every string method returns a new copy. If you don't save that copy to a variable, your changes vanish. Always write let result = myString.trim(); rather than calling myString.trim(); alone.

SECTION 3

Visual Explanation — How split and join Work

split() and join() — Mirror Operations"apple, banana, cherry".split(", ")"apple"index 0"banana"index 1"cherry"index 2["apple", "banana", "cherry"].join(" - ")"apple - banana - cherry"The separator in join() can differ from the one used in split()splitjoin
The diagram shows how split(", ") breaks a comma-separated string into an array of three elements, and join(" - ") reassembles them with a different separator. Notice the original string is never modified — each operation produces a new value.

In the diagram above, the cyan arrow represents the split operation that breaks a single string into an array. The green arrow represents join, which is essentially the reverse. A powerful pattern emerges when you combine them: split a string apart, transform the pieces, then join them back together. This split-transform-join pattern is one of the most common techniques in JavaScript text processing.

SECTION 4

How Each Method Works

split(separator, limit?)

The split method scans the string from left to right. Every time it finds the separator, it slices the text at that point and pushes the piece before the separator into an array. The separator itself is discarded. If you pass an optional limit parameter, the resulting array will contain at most that many elements. Passing an empty string "" as the separator splits every single character into its own array element.

SPLIT SYNTAX

string.split(separator,limit)→Array<string>string.split(separator, limit) → Array<string>

separator — a string or regex that marks where to cut. limit — optional max number of pieces returned.

join(separator)

The join method is called on an array, not a string. It concatenates every element, inserting the separator string between neighbors. If you call join() with no argument, JavaScript defaults to a comma "," as the separator. To glue elements with nothing in between, pass an empty string: join("").

trim(), trimStart(), trimEnd()

Whitespace — spaces, tabs (\t), and newlines (\n) — often sneaks into strings from user input or file parsing. The trim method removes whitespace from both ends of a string but leaves internal spaces alone. Use trimStart() or trimEnd() when you only want to clean one side.

replace(pattern, replacement)

When replace receives a plain string as the pattern, it only replaces the first match. To replace every occurrence, you have two options: use replaceAll(pattern, replacement), or pass a regex with the global flag g. For example, str.replace(/cat/g, "dog") replaces every instance of "cat" with "dog".

REPLACE SYNTAX

string.replace(pattern,replacement)→stringstring.replace(pattern, replacement) → string

pattern — a string or regex. replacement — the text to insert. Only the first match is replaced unless a regex with /g is used.

SECTION 5

Regex Basics — Your First Patterns

A regular expression (regex) is a pattern enclosed in forward slashes. At its simplest, /hello/ matches the literal text "hello". But the real power comes from special characters — called metacharacters — that represent classes of characters or repetition rules. Let's explore the most important ones.

Anatomy of a Regular Expression/[A-Z]\d{2,4}/giOpeningdelimiter /Character class[A-Z] = uppercaseShorthand\d = any digitQuantifier{2,4} = 2 to 4 timesClosing /+ Flagsg = globali = case-insensitiveCommon Metacharacters. = any char\d = digit\w = word char\s = whitespace+ = 1 or more* = 0 or more? = 0 or 1^ $ = anchorsFlags (placed after closing /)g = globali = ignore casem = multilineThe pattern /[A-Z]\d{2,4}/gi matches an uppercase letter followed by 2–4 digits, globally and case-insensitively.
This diagram dissects the regex /[A-Z]\d{2,4}/gi into its components: a character class [A-Z], a digit shorthand \d, a quantifier {2,4}, and the flags g and i. The lower rows show common metacharacters and flags you'll encounter.
SymbolMeaningExample PatternMatches
.Any character except newline/h.t/"hat", "hot", "h3t"
\dAny digit (0–9)/\d\d/"42", "09", "73"
\wWord character (letter, digit, underscore)/\w+/"hello", "user_1"
\sWhitespace (space, tab, newline)/\s+/" ", " "
+One or more of the preceding/go+d/"god", "good", "goood"
*Zero or more of the preceding/bo*k/"bk", "bok", "book"
[ ]Character set — match any one/[aeiou]/Any single vowel
^Start of string/^Hello/"Hello world" (only at start)
$End of string/end$/"the end" (only at end)

Essential regex metacharacters for beginners

💡

REGEX TESTING TIP

Use free online tools like regex101.com to practice. These tools highlight matches in real time and explain every part of your pattern. Set the "flavor" to JavaScript when testing.

SECTION 6

Worked Example — Cleaning & Transforming User Input

Imagine you're building a form that accepts a list of tags typed by a user. The input arrives as a messy string with extra spaces and inconsistent separators. Your goal: produce a clean, lowercase, hyphen-separated string suitable for a URL slug.

From Messy Tags to a Clean URL Slug

  1. 1

    Step 1 — Start with raw input

    The user typed: " JavaScript , Web Dev, Coding ". Notice the leading/trailing spaces, inconsistent spacing around commas, and mixed casing.
    let raw = " JavaScript , Web Dev, Coding ";
  2. 2

    Step 2 — Trim outer whitespace

    Use trim() to remove leading and trailing spaces. This doesn't affect spaces in the middle.
    let trimmed = raw.trim(); → "JavaScript , Web Dev, Coding"
  3. 3

    Step 3 — Split on comma (with optional spaces) using regex

    A plain split(",") would leave spaces stuck to the tag names. Instead, use the regex /\s*,\s*/ which matches a comma surrounded by zero or more spaces.
    let tags = trimmed.split(/\s*,\s*/); → ["JavaScript", "Web Dev", "Coding"]
  4. 4

    Step 4 — Lowercase and replace inner spaces

    Use map to iterate over the array. For each tag, convert to lowercase with toLowerCase() and replace any remaining spaces with hyphens using replace(/\s+/g, "-").
    let cleaned = tags.map(t => t.toLowerCase().replace(/\s+/g, "-")); → ["javascript", "web-dev", "coding"]
  5. 5

    Step 5 — Join into a slug

    Finally, join("-") combines the array back into a single string separated by hyphens.
    let slug = cleaned.join("-"); → "javascript-web-dev-coding"
ℹ

THE FULL PIPELINE

The complete one-liner combining all steps: raw.trim().split(/\s*,\s*/).map(t => t.toLowerCase().replace(/\s+/g, "-")).join("-"). Chaining methods like this is idiomatic JavaScript. Each method returns a new value that the next method operates on.

SECTION 7

String Methods vs. Regex — When to Use Each

You might wonder: if regex can do everything, why bother with plain string methods? The answer is readability and simplicity. Plain string methods are easier to understand at a glance, while regex excels at complex pattern matching. The table below breaks down when to reach for each tool.

TaskPlain String MethodRegex ApproachWhich to Choose?
Remove leading/trailing spacesstr.trim()str.replace(/^\s+|\s+$/g, "")Plain — simpler
Replace first occurrencestr.replace("a", "b")str.replace(/a/, "b")Plain — simpler
Replace all occurrencesstr.replaceAll("a", "b")str.replace(/a/g, "b")Either works; regex more compatible with older browsers
Split on varying delimitersNot possible cleanlystr.split(/[,;|]/)Regex — required
Validate email formatImpractical/^\S+@\S+\.\S+$/.test(str)Regex — required
Extract all numbers from textVery difficultstr.match(/\d+/g)Regex — required

Choosing between string methods and regex

⚖️

RULE OF THUMB

Think of plain string methods as a pair of scissors — perfect for simple, straight cuts. Regex is more like a laser cutter — it can follow any shape, but it takes more skill to operate. Start with the simplest tool that gets the job done, and reach for regex only when you need pattern flexibility.

SECTION 8

Connection to Advanced String Processing

The methods covered in this lesson are your entry point into a much larger world of text processing. As you gain confidence, you'll encounter more advanced techniques that build directly on these foundations. Understanding where these basics lead will help you see why mastering split, join, trim, replace, and regex fundamentals is so important.

What You Learned TodayWhere It Leads
split() and join()Parsing CSV files, tokenizing input for interpreters and compilers, building template engines
trim() for cleaning inputFull input sanitization pipelines, preventing injection attacks in web security
replace() with simple patternsComplex find-and-replace with capture groups, callback functions in replace()
Basic regex metacharactersLookaheads, lookbehinds, named capture groups, and composing large patterns for data validation
match() and test()Full-text search engines, syntax highlighting in code editors, web scraping

From basics to advanced applications

One especially powerful advanced feature is the capture group. By wrapping part of a regex in parentheses — like /(\d{3})-(\d{4})/ — you can extract specific pieces of a match. You'll also eventually learn about matchAll(), which returns an iterator of all matches including their capture groups. These topics are covered in later lessons, but they all rest on the regex fundamentals you're learning now.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain why let name = " Alice "; name.trim(); does NOT change the value of name. What would you need to write instead?
Show answer
Strings in JavaScript are immutable, meaning their methods never modify the original string. The trim() call returns a new string "Alice", but since we didn't assign it to anything, it's immediately discarded. The variable name still holds " Alice ". You need to write name = name.trim(); to capture the result.

Question 2: BASIC CALCULATION

Given let csv = "red,green,blue,yellow";, write code to produce the string "red | green | blue | yellow".
Show answer
First, split the CSV string on commas to get an array: let colors = csv.split(","); which produces ["red", "green", "blue", "yellow"]. Then join them with the new separator: let result = colors.join(" | ");. This yields "red | green | blue | yellow". You could also chain it: csv.split(",").join(" | ").

Question 3: INTERMEDIATE

Write a single expression that takes the string "Hello World! Hello JavaScript!" and replaces every occurrence of "Hello" with "Hi". Show two different approaches.
Show answer
Approach 1 uses replaceAll: "Hello World! Hello JavaScript!".replaceAll("Hello", "Hi"). Approach 2 uses a regex with the global flag: "Hello World! Hello JavaScript!".replace(/Hello/g, "Hi"). Both produce "Hi World! Hi JavaScript!". Note that without the g flag, replace would only change the first "Hello".

Question 4: APPLIED

A form collects phone numbers, but users type them inconsistently: "(555) 123-4567", "555.123.4567", "555 123 4567". Write a function cleanPhone(str) that extracts only the digits and returns them as a single string like "5551234567".
Show answer
Use the regex /\d/g to match every digit globally, then join the results: function cleanPhone(str) { return str.match(/\d/g).join(""); }. Alternatively, you could remove everything that isn't a digit: str.replace(/\D/g, ""). Here \D (uppercase D) means "any non-digit character." Both approaches work for all three input formats, producing "5551234567".

Question 5: CRITICAL THINKING

A student writes "banana".split("a") and gets ["", "n", "n", ""]. They expected ["b", "n", "n"]. Explain why the result contains empty strings. Then write code using split and filter to produce the array without empty strings.
Show answer
When split encounters the separator at the very start of a string, there's nothing before it, so it produces an empty string "" as the first element. Similarly, when the separator is at the very end, an empty string appears at the end of the array. In "banana", the letter "a" appears at positions 1, 3, and 5. Between 'b' and the first 'a' there is "b" — wait, actually the string starts with 'b', so splitting on 'a' gives: before first 'a' is "b"... The result is ["b", "n", "n", ""] — actually the empty string at the end comes because the string ends with 'a'. To remove empty strings, use: "banana".split("a").filter(s => s !== "") or "banana".split("a").filter(Boolean). The filter(Boolean) trick works because empty strings are falsy in JavaScript.

SUMMARY

Lesson Summary

Summary

JavaScript provides a powerful toolkit for working with text. The split() method breaks a string into an array at every occurrence of a separator, while join() reverses the process by gluing array elements into a string. The trim() method strips unwanted whitespace from the edges of a string — critical for cleaning user input. The replace() method swaps the first match of a pattern with new text; to replace all occurrences, use replaceAll() or a regex with the global flag /g.

Regular expressions are patterns written between forward slashes that describe classes of text. Key metacharacters include \d (digit), \w (word character), \s (whitespace), . (any character), and quantifiers like +, *, and ?. Remember that strings are immutable — always save the return value of any string method. The split-transform-join pattern is a versatile approach: break a string apart, process the pieces, and reassemble them.

Varsity Tutors • JavaScript • String Manipulation & Regex — Use split/join/trim/replace and regex basics (intro)