Search and Replace - Finding and Transforming Text with Precision

Learning Objectives: By the end of this lesson, you will be able to:

  • Search for text using various patterns and options
  • Navigate between search results efficiently
  • Perform simple and complex text replacements
  • Use regular expressions for powerful pattern matching
  • Apply search and replace operations across multiple files
  • Understand and use different search modes and flags
  • Handle case sensitivity and word boundaries in searches
  • Use search for navigation and text selection

1. Welcome and Introduction (5 minutes)

Icebreaker Activity

Imagine you’re an archaeologist who needs to find specific artifacts scattered across a vast dig site, then carefully replace damaged pieces with restored ones. Some artifacts are obvious (like searching for “error” in code), while others require pattern recognition (like finding all email addresses). How would you systematically search and replace with precision and speed?

Lesson Overview

  • Duration: 5-6 hours
  • Prerequisites: Comfortable with basic Neovim navigation and text editing
  • Materials Needed: Text files with various content types (code, data, prose)

2. Learning Objectives and Session Outline (5 minutes)

What We’ll Cover Today:

  1. Basic Search Operations - Forward and backward text searching
  2. Search Navigation - Moving between matches efficiently
  3. Simple Replace Operations - Basic find and replace functionality
  4. Regular Expression Basics - Pattern matching fundamentals
  5. Advanced Replace Operations - Complex substitutions with regex
  6. Multi-file Search and Replace - Operations across multiple files
  7. Search Options and Modes - Customizing search behavior
  8. Search-Based Navigation - Using search for efficient movement

Success Criteria:

By the end of this session, you should find any text in any file within seconds, perform complex text transformations using patterns, and handle large-scale refactoring operations across multiple files.

3. Foundation Knowledge (15-20 minutes)

The Philosophy of Search and Replace

Search and replace in Neovim is fundamentally different from traditional editors. It’s not just about finding text—it’s about pattern recognition, precise selection, and powerful transformation.

Real-World Analogy: Think of search and replace like being a detective with a DNA scanner. Basic search is like looking for a suspect by appearance (exact matches), while regex search is like DNA analysis (pattern matching). Replace operations are like systematically updating evidence files with new information.

Why This Matters: Neovim’s search and replace provides:

  • Precision: Find exactly what you’re looking for with pattern matching
  • Efficiency: Navigate large files faster than scrolling
  • Power: Transform text in ways that would take hours manually
  • Consistency: Reliable operations that work across all file types

Search and Replace Hierarchy

  • Simple string matching
  • Case-sensitive and case-insensitive options
  • Forward and backward searching
  • Word boundary matching

2. Pattern-Based Search (Regex)

  • Pattern matching with wildcards and character classes
  • Quantifiers for repetition
  • Groups for complex patterns
  • Anchors for position-specific matching

3. Replace Operations

  • Simple text replacement
  • Pattern-based replacement with captured groups
  • Conditional replacements
  • Multi-line replacements

4. Scope and Range

  • Current line replacements
  • Selected text replacements
  • Entire file operations
  • Multi-file operations

Key Terminology

  • Pattern: Text or regex used for searching
  • Match: Text that fits the search pattern
  • Capture Group: Part of regex pattern that can be referenced in replacement
  • Substitution: Replace operation with pattern and replacement text
  • Flag: Option that modifies search/replace behavior
  • Range: Scope of lines where operation applies

4. Detailed Explanation and Examples (25-30 minutes)

Basic Search Operations

Search is one of the most fundamental operations in text editing, providing both text location and navigation functionality.

/pattern          " Search forward for pattern
?pattern          " Search backward for pattern
n                 " Next match (same direction)
N                 " Previous match (opposite direction)

Search Navigation

*                 " Search forward for word under cursor
#                 " Search backward for word under cursor
g*                " Search forward for partial word under cursor
g#                " Search backward for partial word under cursor

Search Options

/pattern\c        " Case insensitive search
/pattern\C        " Case sensitive search
/\<pattern\>      " Whole word search
/^pattern         " Search at beginning of line
/pattern$         " Search at end of line

Basic Replace Operations

The substitute command (:s) is the foundation of text replacement in Neovim.

Basic Substitute Syntax

:s/old/new/           " Replace first occurrence on current line
:s/old/new/g          " Replace all occurrences on current line
:%s/old/new/g         " Replace all occurrences in entire file
:s/old/new/gc         " Replace with confirmation

Range-Based Replacements

:1,10s/old/new/g      " Replace in lines 1-10
:.,$s/old/new/g       " Replace from current line to end
:'<,'>s/old/new/g     " Replace in visual selection

Regular Expression Fundamentals

Regular expressions unlock powerful pattern matching capabilities for complex search and replace operations.

Basic Regex Elements

.                 " Any character
*                 " Zero or more of previous
\+                " One or more of previous
\?                " Zero or one of previous
\{n,m}            " Between n and m of previous
^                 " Beginning of line
$                 " End of line
\<                " Beginning of word
\>                " End of word

Character Classes

[abc]             " Any of a, b, or c
[a-z]             " Any lowercase letter
[0-9]             " Any digit
[^abc]            " Any character except a, b, or c
\d                " Any digit
\s                " Any whitespace
\w                " Any word character

Capture Groups and Backreferences

\(pattern\)       " Capture group
\1, \2, \3        " Reference captured groups in replacement

5. Live Coding Demonstration (20-25 minutes)

Demonstration 1: Basic Search and Navigation

Working with this JavaScript code:

function calculateUserScore(userData) {
    const userName = userData.name;
    const userAge = userData.age;
    const userEmail = userData.email;
    
    if (userName && userAge > 18) {
        return processUser(userName, userAge, userEmail);
    }
    return null;
}

Task: Find and navigate through all occurrences of “user”

  1. Start search:

    /user
    
  2. Navigate through matches:

    n          " Next occurrence
    N          " Previous occurrence
    
  3. Search for whole word only:

    /\<user\>   " Find "user" as complete word
    
  4. Use cursor-based search:

    *          " Position cursor on "user" and press *
    

Demonstration 2: Simple Text Replacement

Using the same JavaScript code, let’s rename variables:

Task: Change all “user” prefixes to “customer”

  1. Replace on current line:

    :s/user/customer/g
    
  2. Replace in entire file:

    :%s/user/customer/g
    
  3. Replace with confirmation:

    :%s/user/customer/gc
    

Demonstration 3: Advanced Regex Replacement

Working with this data file:

John Doe, john.doe@email.com, (555) 123-4567
Jane Smith, jane.smith@email.com, (555) 987-6543
Bob Johnson, bob.johnson@email.com, (555) 456-7890

Task: Format phone numbers consistently

  1. Search for phone pattern:

    /(\d\{3}) \d\{3}-\d\{4}
    
  2. Replace with new format:

    :%s/(\(\d\{3}\)) \(\d\{3}\)-\(\d\{4}\)/\1-\2-\3/g
    
  3. Result:

    John Doe, john.doe@email.com, 555-123-4567
    Jane Smith, jane.smith@email.com, 555-987-6543
    Bob Johnson, bob.johnson@email.com, 555-456-7890
    

6. Hands-On Practice (30-40 minutes)

Exercise 1: Basic Search Mastery (10 minutes)

Objective: Master fundamental search operations and navigation

Text Sample:

def process_data(data_list):
    processed_data = []
    for data_item in data_list:
        if validate_data(data_item):
            cleaned_data = clean_data(data_item)
            processed_data.append(cleaned_data)
    return processed_data

def validate_data(data):
    return data is not None and len(data) > 0

def clean_data(data):
    return data.strip().lower()

Tasks:

  1. Find all occurrences of “data”:

    • Search forward: /data
    • Navigate through all matches using n and N
    • Count total occurrences
  2. Search for specific patterns:

    • Find “data” at the beginning of words: /\<data
    • Find “data” at the end of words: /data\>
    • Find whole word “data” only: /\<data\>
  3. Use cursor-based search:

    • Position cursor on “process” and use *
    • Use # to search backward
    • Try g* for partial matches

Exercise 2: Simple Replace Operations (15 minutes)

Objective: Practice basic find and replace operations

Starting Code:

<div class="container">
    <h1 class="title">Welcome</h1>
    <p class="text">This is some sample text content.</p>
    <div class="box">
        <span class="label">Name:</span>
        <input class="input" type="text" />
    </div>
    <div class="box">
        <span class="label">Email:</span>
        <input class="input" type="email" />
    </div>
</div>

Tasks:

  1. Replace class names:

    • Change “container” to “wrapper”: :%s/container/wrapper/g
    • Change “box” to “field”: :%s/box/field/g
  2. Update attributes:

    • Change all “class” to “className”: :%s/class/className/g
  3. Replace with confirmation:

    • Change “text” to “content” with confirmation: :%s/text/content/gc
  4. Line-specific replacement:

    • On the input lines only, change “input” to “form-control”
    • Use visual selection: V to select lines, then :'<,'>s/input/form-control/g

Exercise 3: Regular Expression Power (15 minutes)

Objective: Use regex patterns for complex find and replace operations

Data File:

Name,Email,Phone,Date
John Smith,john.smith@company.com,555-123-4567,2023-01-15
Jane Doe,jane.doe@company.com,555-987-6543,2023-02-20
Bob Johnson,bob.johnson@company.com,555-456-7890,2023-03-10
Alice Brown,alice.brown@company.com,555-321-9876,2023-04-05

Tasks:

  1. Find email patterns:

    • Search for email addresses: /\w\+@\w\+\.com
    • Navigate through all email matches
  2. Replace email domains:

    • Change all “.com” to “.org”: :%s/\.com/.org/g
  3. Format phone numbers:

    • Change from “555-123-4567” to “(555) 123-4567”
    • Pattern: :%s/\(\d\{3}\)-\(\d\{3}\)-\(\d\{4}\)/(\1) \2-\3/g
  4. Extract and reorganize names:

    • Change “John Smith” to “Smith, John”
    • Pattern: :%s/\(\w\+\) \(\w\+\)/\2, \1/g
  5. Date format conversion:

    • Change “2023-01-15” to “01/15/2023”
    • Pattern: :%s/\(\d\{4}\)-\(\d\{2}\)-\(\d\{2}\)/\2\/\3\/\1/g

7. Common Pitfalls and Troubleshooting (10 minutes)

Frequent Mistakes

  1. Problem: Search doesn’t find obvious matches Cause: Case sensitivity or word boundary issues Solution: Use appropriate flags and options

    /pattern\c        " Case insensitive
    /\<pattern\>      " Whole word only
    set ignorecase    " Default case insensitive
    set smartcase     " Case sensitive if capitals used
    
  2. Problem: Regex pattern doesn’t work as expected Cause: Neovim uses different regex syntax than other tools Solution: Use Neovim-specific syntax or magic mode

    /\v(pattern)      " Very magic mode (more standard regex)
    /\V[literal]      " Very nomagic mode (literal search)
    
  3. Problem: Replace operation affects wrong text Cause: Pattern matches more than intended Solution: Use more specific patterns and test first

    :%s/old/new/gc    " Use confirmation flag
    /pattern          " Test search pattern first
    
  4. Problem: Can’t undo complex replace operation Cause: Large operation without breaking points Solution: Use confirmation or break into smaller operations

    :undojoin | s/old/new/g    " Join with previous undo
    

Search Configuration

Enhancing Search Behavior

-- Add to init.lua
vim.opt.hlsearch = true      -- Highlight search results
vim.opt.incsearch = true     -- Show matches while typing
vim.opt.ignorecase = true    -- Ignore case by default
vim.opt.smartcase = true     -- Case sensitive if capitals used
vim.opt.wrapscan = true      -- Wrap around end of file

-- Clear search highlight
vim.keymap.set("n", "<leader>/", ":nohlsearch<CR>")

Advanced Search Techniques

/pattern\_.*pattern     " Search across multiple lines
/begin\_.\{-}end        " Non-greedy multi-line match

Search History

/<Up>              " Previous search
/<Down>            " Next search
q/                 " Open search history window

8. Best Practices and Professional Tips (5 minutes)

Efficient Search Workflows

Search Strategy

  1. Start specific: Use exact strings when possible
  2. Add patterns gradually: Build complex regex step by step
  3. Test before replacing: Always search first, then replace
  4. Use confirmation for large operations: Safety with /gc flag
" Quick search mappings
nnoremap <leader>/ /
nnoremap <leader>? ?
nnoremap <silent> <leader>h :nohlsearch<CR>

Replace Patterns

" Common replace operations
:%s/\s\+$//g               " Remove trailing whitespace
:%s/\n\{3,}/\r\r/g         " Replace multiple blank lines with two
:%s/\v([a-z])([A-Z])/\1_\L\2/g  " camelCase to snake_case

Advanced Search and Replace

Multi-file Operations

:args *.js                 " Load JS files
:argdo %s/old/new/ge       " Replace in all loaded files
:argdo update              " Save all files

Complex Transformations

" Convert function declarations
:%s/\vfunction (\w+)\(([^)]*)\)/const \1 = (\2) =>/g

" Format JSON-like data
:%s/\v"(\w+)": "([^"]+)"/"\1": "\2"/g

" Clean up whitespace
:%s/\v\s+/ /g              " Multiple spaces to single
:%s/\v^\s+//g              " Leading whitespace
:%s/\v\s+$//g              " Trailing whitespace

Search-Based Refactoring

Variable Renaming Workflow

  1. Search for variable: /oldName
  2. Verify all occurrences with n
  3. Replace with confirmation: :%s/oldName/newName/gc
  4. Review changes before saving

Code Pattern Updates

" Update console.log to logger.info
:%s/console\.log(/logger.info(/g

" Convert arrow functions
:%s/\v(\w+) => \{/function(\1) {/g

9. Summary and Review (5 minutes)

Key Takeaways

  1. Search is navigation: Use search to move around files efficiently
  2. Pattern power: Regular expressions unlock complex text transformations
  3. Safety first: Always test patterns before large replace operations
  4. Scope awareness: Understand what range your operation will affect
  5. Build incrementally: Start simple and add complexity gradually

Essential Command Categories

" Basic search: /, ?, n, N, *, #
" Simple replace: :s/old/new/g, :%s/old/new/g
" Regex patterns: \d, \w, \s, \+, *, \{n,m}
" Capture groups: \(pattern\), \1, \2
" Flags: g, c, i, I

Quick Review Questions

  1. How do you search for a whole word only?
  2. What’s the difference between n and N in search navigation?
  3. How do you replace all occurrences in the entire file with confirmation?
  4. How do you reference captured groups in replacement text?
  5. How do you make a search case insensitive?

Answers:

  1. /\<word\> or use * when cursor is on the word
  2. n continues in same direction as search, N goes opposite direction
  3. :%s/old/new/gc
  4. Use \1, \2, etc. to reference groups defined with \(pattern\)
  5. /pattern\c or set ignorecase option

Building Search and Replace Mastery

Progression Path

  • Week 1: Master basic search and simple replacements
  • Week 2: Learn regex fundamentals and pattern building
  • Week 3: Complex transformations and multi-file operations
  • Week 4: Advanced patterns and workflow integration

Daily Practice

  • Use search for navigation: Replace scrolling with targeted searching
  • Practice patterns: Build regex skills with real-world text
  • Refactor regularly: Use search/replace for code improvements
  • Explore text: Use search to understand unfamiliar codebases

For Instructors

Teaching Tips

  • Start with examples students recognize: Use familiar text types and patterns
  • Build regex gradually: Don’t overwhelm with complex patterns initially
  • Show mistakes: Demonstrate what happens when patterns go wrong
  • Practice recovery: Teach undo and how to fix failed operations
  • Use real data: Practice with actual files students work with

Assessment Ideas

  • Pattern building tests: Present text transformation requirements
  • Speed challenges: Time students finding specific patterns
  • Regex translation: Convert requirements to working patterns
  • Refactoring exercises: Use search/replace for code modernization

Adaptation Notes

  • Different text types: Adapt examples to students’ primary work (data, code, documentation)
  • Skill levels: Advanced students can learn lookahead/lookbehind and complex patterns
  • Language differences: Some regex features vary by programming language
  • Performance considerations: Teach efficient patterns for large files

Common Student Questions

  • “Why learn regex when I can do it manually?” - Demonstrate time savings on large operations
  • “This seems too complex” - Show how patterns build incrementally
  • “What if I break something?” - Emphasize undo system and confirmation flags
  • “When would I use this in real work?” - Provide concrete examples from their domain

Remember: Search and replace mastery transforms text editing from tedious character-by-character work to powerful pattern-based operations. This skill multiplies productivity in all text-based work.