Skip to main content

How to Get a Substring Between Two Characters in a String in JavaScript

Extracting a piece of text that lies between two specific characters or delimiters is a common string parsing task. For example, you might need to get the content inside parentheses (), brackets [], or between a known prefix and suffix. The most powerful and flexible tool for this is a regular expression.

This guide will teach you how to use a regular expression with the match() method to reliably extract a substring. We will also cover a more manual approach using indexOf and slice for simpler cases.

The Core Problem: Extracting Enclosed Text

The goal is to isolate and retrieve the content that is between two different delimiters.

For example, how do we extract the content 'reference' from this string?

const myString = 'tutorial_reference#com';

We need a method that can find the starting delimiter (_), the ending delimiter (#), and return everything in between.

Regular expressions are the definitive tool for pattern matching. The String.prototype.match() method, when used with a regex containing a "capturing group," can extract the desired substring in a single, powerful step.

This is the recommended solution because of its flexibility and power.

function getSubstringBetween(str, startChar, endChar) {
// Create a dynamic regular expression
const regex = new RegExp(`${startChar}(.*?)${endChar}`);
const match = str.match(regex);

// If a match is found, the captured group is at index 1.
// Otherwise, return null or an empty string.
return match ? match[1] : null;
}

// Example Usage:
const myString = 'tutorial_reference#com';

const result = getSubstringBetween(myString, '_', '#');
console.log(result); // Output: "reference"

How the Regular Expression Works

Let's break down the regex /_ (.*?) #/:

  • _: Matches the literal starting character.
  • (...): This is a capturing group. It tells the regex engine that we want to "capture" whatever is matched inside the parentheses. This is the part we want to extract.
  • .*?: This is the core of the match.
    • .: Matches any character (except a newline).
    • *: Is a quantifier meaning "zero or more times."
    • ?: Makes the * non-greedy. This is crucial. It tells the engine to match the shortest possible string until it finds the end character. Without this, it might match too much.
  • #: Matches the literal ending character.

When str.match(regex) is called:

  • If there is a match, it returns an array: ['matched_string', 'captured_group_1', 'captured_group_2', ...].
  • Our desired content is always at index 1.

The Manual Method: Using indexOf and slice

For simple cases, you can achieve this by manually finding the positions of the start and end characters and then "slicing" the string.

function getSubstringBetween(str, startChar, endChar) {
const startIndex = str.indexOf(startChar);
if (startIndex === -1) {
return null; // Start character not found
}

// Adjust startIndex to be after the start character
const adjustedStart = startIndex + startChar.length;

const endIndex = str.indexOf(endChar, adjustedStart);
if (endIndex === -1) {
return null; // End character not found after start character
}

return str.slice(adjustedStart, endIndex);
}

// Example Usage:
const myString = 'tutorial_reference#com';
const result = getSubstringBetween(myString, '_', '#');
console.log(result); // Output: "reference"

While functional, this method is more verbose and less flexible than the regex approach, especially if the delimiters are multi-character strings or have complex patterns.

What Happens When the Characters Are Not Found

A robust solution must handle cases where the delimiters are missing.

  • Regex Method: str.match() will return null if the pattern is not found. Our function handles this by also returning null.
  • Manual Method: indexOf() returns -1 if a character is not found. Our function includes checks for this and returns null.

Both methods can be easily adapted to return an empty string ('') or throw an error, depending on the desired behavior.

Conclusion

For extracting a substring between two delimiters, JavaScript offers two primary solutions.

  • The manual indexOf and slice method is a straightforward, imperative approach that works well for simple, single-character delimiters.
  • The regular expression method is the recommended best practice. It is more powerful, more flexible (especially with multi-character or complex delimiters), and often more concise.

By using a regex with a non-greedy capturing group ((.*?)), you can create a robust and declarative solution for nearly any string extraction task.