Escape Special Characters in PHP Regex using preg_quote

When working with regular expressions in PHP, characters like ., +, *, or ? have special meanings. If you need to treat these characters as literal text within a pattern—for example, when matching user input—they must be properly escaped. This article explains how to use PHP’s built-in preg_quote() function to safely escape special characters and prevent regular expression injection vulnerabilities.

What is preg_quote()?

preg_quote() is a built-in PHP function that takes a string and places a backslash (\) before every character that is part of the regular expression syntax.

By default, the function escapes the following characters: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : - #

Syntax

string preg_quote ( string $str [, string $delimiter = NULL ] )

Basic Usage

If you have a string that contains special regex characters and you want to match it exactly as a literal string, pass it through preg_quote().

<?php
$userInput = "Questions? Yes+No.";
$escaped = preg_quote($userInput);

echo $escaped; 
// Output: Questions\? Yes\+No\.
?>

Escaping the Delimiter

The most common mistake when using preg_quote() is forgetting to escape the regex delimiter. In PHP, regular expressions are typically wrapped in delimiters like /. If your input string contains a /, it will prematurely close your regex pattern and trigger a compilation error.

To solve this, pass your delimiter as the second argument to preg_quote().

<?php
$url = "https://example.com/search?q=php";

// Without the delimiter parameter (fails if pattern uses /)
$badEscaped = preg_quote($url);
// Output: https://example\.com/search\?q=php (Note that "/" is NOT escaped)

// With the delimiter parameter (safe)
$goodEscaped = preg_quote($url, '/');
// Output: https\:\/\/example\.com\/search\?q=php (Note that "/" IS escaped)
?>

Practical Example: Matching User Input Safely

Below is a complete example showing how to safely use user-supplied search terms inside a preg_match query.

<?php
$haystack = "The price of the item is $10.99 USD.";
$searchTerm = "$10.99";

// 1. Escape the search term and specify '/' as the delimiter
$safeSearchTerm = preg_quote($searchTerm, '/');

// 2. Construct the regex pattern
$pattern = '/' . $safeSearchTerm . '/';

// 3. Perform the match
if (preg_match($pattern, $haystack)) {
    echo "Match found!";
} else {
    echo "No match found.";
}
// Output: Match found!
?>