Emacs: how to replace a string using a regular expression?

Learn emacs: how to replace a string using a regular expression? with practical examples, diagrams, and best practices. Covers regex, emacs, replace development techniques with visual explanations.

Mastering Regex Replacement in Emacs

Hero image for Emacs: how to replace a string using a regular expression?

Learn how to efficiently replace strings using regular expressions in Emacs, covering interactive commands and advanced techniques.

Emacs, a powerful and extensible text editor, offers robust capabilities for text manipulation, including sophisticated search and replace operations using regular expressions (regex). This article will guide you through the fundamental commands and advanced features to perform regex-based string replacements, enhancing your text editing workflow.

Interactive Regex Replacement: query-replace-regexp

The primary command for interactive regex replacement in Emacs is query-replace-regexp. This command allows you to specify a regular expression to search for and a replacement string. Emacs then prompts you for each match, giving you control over whether to replace, skip, or perform other actions.

M-x query-replace-regexp

;; Or using the keybinding:
C-M-%

Invoking query-replace-regexp

When you execute query-replace-regexp, Emacs will prompt you in the minibuffer for two inputs:

  1. Regexp to search for: Enter your regular expression here. For example, \(foo\)bar to match "foobar" and capture "foo".
  2. Replace with: Enter your replacement string. You can use backreferences like \1 to refer to captured groups from your regex. For example, \1baz would replace "foobar" with "foobaz" if \(foo\)bar was the search regex.

Understanding Replacement Actions

After entering your search regex and replacement string, Emacs will find the first match and prompt you with a series of options. Here are the most common actions you can take:

flowchart TD
    A[Start `query-replace-regexp`]
    B{Match Found?}
    C[Prompt for Action]
    D{Replace this match?}
    E[Replace and move to next]
    F[Skip this match]
    G[Replace all remaining]
    H[Quit replacement]
    I[Replace and exit]
    J[Replace and edit]
    K[Go back to previous match]
    L[No more matches]
    M[End]

    A --> B
    B -- Yes --> C
    C --> D
    D -- y --> E --> B
    D -- n --> F --> B
    D -- ! --> G --> L
    D -- q --> H --> M
    D -- . --> I --> M
    D -- e --> J --> B
    D -- ^ --> K --> B
    B -- No --> L --> M

Flowchart of query-replace-regexp actions

The most common actions are:

  • y (yes): Replace the current match and move to the next.
  • n (no): Skip the current match and move to the next.
  • ! (replace all): Replace all remaining matches without further prompting.
  • q (quit): Exit the replacement process.
  • . (replace and exit): Replace the current match and then exit.
  • e (edit): Replace the current match and then enter a recursive edit to manually adjust the replacement.
  • ^ (previous): Go back to the previous match.

Non-Interactive Regex Replacement: replace-regexp

For situations where you want to replace all occurrences of a regex without interactive confirmation, Emacs provides the replace-regexp command. This is useful for large-scale, confident replacements.

M-x replace-regexp

;; Or using the keybinding:
C-M-C-r

Invoking replace-regexp

Similar to query-replace-regexp, you will be prompted for the regex to search for and the replacement string. However, once you provide both, Emacs will perform all replacements immediately without asking for confirmation for each match.

Advanced Regex Features and Backreferences

Emacs regex supports powerful features, including capturing groups and backreferences, which are crucial for complex replacements. A capturing group is defined by enclosing a part of the regex in \( and \). The matched content of these groups can then be referred to in the replacement string using \1, \2, and so on, corresponding to the order of the capturing groups.

;; Example: Swapping 'first_name, last_name' to 'last_name first_name'

;; Search regex:
\([[:alnum:]_]+\), \([[:alnum:]_]+\)

;; Replacement string:
\2 \1

;; This would transform "John, Doe" into "Doe John"

Using capturing groups and backreferences

Here, \([[:alnum:]_]+\) captures a sequence of alphanumeric characters or underscores. The first such sequence is referenced by \1, and the second by \2 in the replacement string.