R
Regex Master
TutorialsToolsFAQAboutContact
  1. Home
  2. Tutorials
  3. Programming
  4. PHP Regex Functions: preg_match vs preg_replace
June 29, 2024Regex Master Team9 min read

PHP Regex Functions: preg_match vs preg_replace

Programmingphpregexpreg-matchpreg-replaceprogramming

Deep dive into PHP regex functions, understand the differences between preg_match and preg_replace, and learn correct usage.

PHP provides powerful PCRE (Perl Compatible Regular Expressions) support, with preg_match and preg_replace being the most commonly used functions. This article will compare these functions in detail, helping you master the correct usage of PHP regular expressions.

PHP Regex Functions Overview

Main Function Categories

CategoryFunctionPurpose
Matchingpreg_match()Perform single match
Matchingpreg_match_all()Perform all matches
Replacepreg_replace()Perform regex replacement
Replacepreg_replace_callback()Replace with callback function
Splitpreg_split()Split string using regex
Filterpreg_filter()Similar to preg_replace, returns differences
Grouppreg_grep()Filter array elements

Function Selection Guide

Need to match?
  → Match once: preg_match()
  → Match all: preg_match_all()

Need to replace?
  → Simple replacement: preg_replace()
  → Complex logic: preg_replace_callback()

Need to split?
  → preg_split()

Need to filter array?
  → preg_grep()

preg_match() Series

1. preg_match() - Single Match

Basic Usage

<?php
$pattern = '/\d+/';
$subject = "Hello 123 World";

// Returns match count (0 or 1)
$count = preg_match($pattern, $subject, $matches);

if ($count > 0) {
    echo "Match found: " . $matches[0] . "\n";  // 123
}
?>

Get Position Information

<?php
$pattern = '/\d+/';
$subject = "abc123def";

// Use PREG_OFFSET_CAPTURE to get position
$count = preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);

if ($count > 0) {
    echo "Match: " . $matches[0][0] . "\n";      // 123
    echo "Position: " . $matches[0][1] . "\n";      // 3
}
?>

Use Flags

<?php
// PREG_OFFSET_CAPTURE - Get position
preg_match('/\d+/', "abc123", $matches, PREG_OFFSET_CAPTURE);

// PREG_UNMATCHED_AS_NULL - Unmatched groups return null
preg_match('/(\d+)(\w+)?/', "123", $matches, PREG_UNMATCHED_AS_NULL);
// $matches[2] is null instead of empty string
?>

2. preg_match_all() - Global Match

Basic Usage

<?php
$pattern = '/\d+/';
$subject = "a1b2c3d4";

// Returns match count
$count = preg_match_all($pattern, $subject, $matches);

echo "Match count: " . $count . "\n";  // 4
print_r($matches[0]);  // ["1", "2", "3", "4"]
?>

Sort Order

<?php
$pattern = '/(\d)(\w+)/';
$subject = "1a 2b 3c";

// PREG_PATTERN_ORDER (default) - Sort by groups
preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER);
print_r($matches);
/*
Array (
    [0] => Array ([0] => 1a [1] => 2b [2] => 3c)
    [1] => Array ([0] => 1  [1] => 2  [2] => 3)
    [2] => Array ([0] => a  [1] => b  [2] => c)
)
*/

// PREG_SET_ORDER - Sort by match sets
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
print_r($matches);
/*
Array (
    [0] => Array ([0] => 1a [1] => 1 [2] => a)
    [1] => Array ([0] => 2b [1] => 2 [2] => b)
    [2] => Array ([0] => 3c [1] => 3 [2] => c)
)
*/
?>

Get Position Information

<?php
$pattern = '/\d+/';
$subject = "a1b2c3";

preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
print_r($matches[0]);
/*
Array (
    [0] => Array ([0] => 1 [1] => 1)
    [1] => Array ([0] => 2 [1] => 3)
    [2] => Array ([0] => 3 [1] => 5)
)
*/
?>

3. preg_match() vs preg_match_all()

Usage Scenario Comparison

<?php
$email = "[email protected], [email protected]";

// Only need to know if email exists
if (preg_match('/[\w.+-]+@[\w.-]+\.[a-z]{2,}/', $email)) {
    echo "Contains email address\n";
}

// Need to extract all emails
preg_match_all('/[\w.+-]+@[\w.-]+\.[a-z]{2,}/', $email, $matches);
print_r($matches[0]);  // ["[email protected]", "[email protected]"]
?>

Performance Comparison

<?php
$text = str_repeat("test 123 ", 1000);

// preg_match() - Only checks first match
preg_match('/\d+/', $text);  // Fast

// preg_match_all() - Finds all matches
preg_match_all('/\d+/', $text, $matches);  // Slower, needs to traverse entire string
?>

preg_replace() Series

1. preg_replace() - Basic Replacement

Basic Usage

<?php
$pattern = '/\d+/';
$replacement = '[number]';
$subject = "Price: 100, 200, 300";

$result = preg_replace($pattern, $replacement, $subject);
echo $result;  // Price: [number], [number], [number]
?>

Limit Replacement Count

<?php
$pattern = '/a/';
$replacement = 'b';
$subject = "a-a-a-a";

// Only replace first two
$result = preg_replace($pattern, $replacement, $subject, 2);
echo $result;  // b-b-a-a
?>

Use Group References

<?php
$pattern = '/(\d{4})-(\d{2})-(\d{2})/';
$replacement = '$2/$3/$1';  // Reference groups
$subject = "2024-01-25";

$result = preg_replace($pattern, $replacement, $subject);
echo $result;  // 01/25/2024
?>

Replace Multiple Patterns

<?php
$patterns = ['/apple/', '/banana/', '/orange/'];
$replacements = ['apple', 'banana', 'orange'];
$subject = "I like apple, banana, and orange";

$result = preg_replace($patterns, $replacements, $subject);
echo $result;  // I like apple, banana, and orange
?>

2. preg_replace_callback() - Callback Replacement

Basic Usage

<?php
$pattern = '/\d+/';
$subject = "Price: 100, 200, 300";

$result = preg_replace_callback($pattern, function($matches) {
    $num = intval($matches[0]);
    return $num * 0.9;  // Apply 10% discount
}, $subject);

echo $result;  // Price: 90, 180, 270
?>

Complex Logic Replacement

<?php
$pattern = '/#(\w+)/';
$subject = "Check out #PHP and #Regex";

$result = preg_replace_callback($pattern, function($matches) {
    $tag = $matches[1];
    return "<a href='/tag/$tag'>#$tag</a>";
}, $subject);

echo $result;  // Check out <a href='/tag/PHP'>#PHP</a> and <a href='/tag/Regex'>#Regex</a>
?>

Use Array Callback

<?php
class TagReplacer {
    public function replace($matches) {
        return strtoupper($matches[1]);
    }
}

$pattern = '/(\w+)/';
$subject = "hello world";
$replacer = new TagReplacer();

$result = preg_replace_callback($pattern, [$replacer, 'replace'], $subject);
echo $result;  // HELLO WORLD
?>

3. preg_replace() vs preg_replace_callback()

Simple Replacement - preg_replace()

<?php
// Simple string replacement
$result = preg_replace('/\d+/', 'number', '123 456');
?>

Complex Logic - preg_replace_callback()

<?php
// Need calculation or conditional logic
$result = preg_replace_callback('/\d+/', function($matches) {
    $num = intval($matches[0]);
    if ($num > 100) {
        return $num * 0.8;
    }
    return $num;
}, '50 150 200');
?>

Other Important Functions

1. preg_split() - Split String

Basic Usage

<?php
$pattern = '/[,;|]/';
$subject = "apple,banana;orange|grape";

$parts = preg_split($pattern, $subject);
print_r($parts);  // ["apple", "banana", "orange", "grape"]
?>

Limit Split Count

<?php
$pattern = '/[,;]/';
$subject = "a,b,c,d,e";

$parts = preg_split($pattern, $subject, 2);
print_r($parts);  // ["a", "b,c,d,e"]
?>

Keep Whitespace

<?php
$pattern = '/\s+/';
$subject = "a  b   c";

$parts = preg_split($pattern, $subject, -1, PREG_SPLIT_NO_EMPTY);
print_r($parts);  // ["a", "b", "c"]
?>

2. preg_grep() - Filter Array

Basic Usage

<?php
$pattern = '/^\d+$/';
$array = ["123", "abc", "456", "def"];

// Matched elements
$matched = preg_grep($pattern, $array);
print_r($matched);  // ["123", "456"]

// Non-matched elements (use PREG_GREP_INVERT)
$notMatched = preg_grep($pattern, $array, PREG_GREP_INVERT);
print_r($notMatched);  // ["abc", "def"]
?>

3. preg_filter() - Conditional Replacement

<?php
$pattern = '/\d+/';
$replacement = 'number';
$subjects = ["test 123", "no numbers", "456 end"];

// Only replace strings containing matches
$result = preg_filter($pattern, $replacement, $subjects);
print_r($result);  // ["test number", "456 end"]
?>

Practical Examples

Example 1: Validate Email

<?php
function isValidEmail($email) {
    $pattern = '/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/';
    return preg_match($pattern, $email) === 1;
}

var_dump(isValidEmail("[email protected]"));  // true
var_dump(isValidEmail("invalid.email"));      // false
?>

Example 2: Extract All Emails

<?php
function extractEmails($text) {
    $pattern = '/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/';
    preg_match_all($pattern, $text, $matches);
    return $matches[0];
}

$text = "Contact: [email protected], [email protected]";
print_r(extractEmails($text));
// ["[email protected]", "[email protected]"]
?>

Example 3: Clean HTML Tags

<?php
function stripHTML($html) {
    $pattern = '/<[^>]+>/';
    return preg_replace($pattern, '', $html);
}

$html = "<p>Hello <b>World</b>!</p>";
echo stripHTML($html);  // Hello World!
?>

Example 4: BBCode Parser

<?php
function parseBBCode($text) {
    // [b]bold[/b]
    $text = preg_replace('/\[b\](.*?)\[\/b\]/s', '<b>$1</b>', $text);

    // [i]italic[/i]
    $text = preg_replace('/\[i\](.*?)\[\/i\]/s', '<i>$1</i>', $text);

    // [url=link]text[/url]
    $text = preg_replace('/\[url=([^\]]+)\](.*?)\[\/url\]/s', '<a href="$1">$2</a>', $text);

    return $text;
}

$bbcode = "[b]bold[/b] and [i]italic[/i]";
echo parseBBCode($bbcode);
// <b>bold</b> and <i>italic</i>
?>

Example 5: Phone Number Masking

<?php
function maskPhone($phone) {
    $pattern = '/(\d{3})\d{4}(\d{4})/';
    return preg_replace($pattern, '$1****$2', $phone);
}

echo maskPhone("13812345678");  // 138****5678
?>

Example 6: Extract URL Parameters

<?php
function extractURLParams($url) {
    $pattern = '/[?&]([^=]+)=([^&]+)/';
    preg_match_all($pattern, $url, $matches);

    $params = [];
    foreach ($matches[1] as $index => $key) {
        $params[$key] = $matches[2][$index];
    }

    return $params;
}

$url = "https://example.com?name=John&age=30&city=NYC";
print_r(extractURLParams($url));
// ["name" => "John", "age" => "30", "city" => "NYC"]
?>

Example 7: Markdown Conversion

<?php
function convertMarkdown($text) {
    # Headers
    $text = preg_replace('/^# (.+)$/m', '<h1>$1</h1>', $text);
    $text = preg_replace('/^## (.+)$/m', '<h2>$1</h2>', $text);
    $text = preg_replace('/^### (.+)$/m', '<h3>$1</h3>', $text);

    # Bold
    $text = preg_replace('/\*\*(.+?)\*\*/', '<strong>$1</strong>', $text);

    # Italic
    $text = preg_replace('/\*(.+?)\*/', '<em>$1</em>', $text);

    # Links
    $text = preg_replace('/\[([^\]]+)\]\(([^)]+)\)/', '<a href="$2">$1</a>', $text);

    return $text;
}

$markdown = "**bold** and *italic* [link](http://example.com)";
echo convertMarkdown($markdown);
// <strong>bold</strong> and <em>italic</em> <a href="http://example.com">link</a>
?>

Best Practices

1. Use Delimiters

<?php
// Good practice: Use delimiters
$pattern = '/\d+/';

// Can also use other characters
$pattern = '#\d+#';
$pattern = '!\d+!';
?>

2. Use Single Quotes

<?php
// Good practice: Use single quotes (safer)
$pattern = '/\d+/';

// Bad practice: Use double quotes (might accidentally parse variables)
$pattern = "/\d+/";
?>

3. Check Return Values

<?php
// Good practice: Check return values
if (preg_match('/\d+/', $text, $matches)) {
    echo $matches[0];
}

// Bad practice: Don't check
preg_match('/\d+/', $text, $matches);
echo $matches[0];  // Might be undefined index
?>

4. Use Non-Greedy Matching

<?php
// Good practice: Non-greedy
$pattern = '/<div>.*?<\/div>/';

// Bad practice: Greedy
$pattern = '/<div>.*<\/div>/';
?>

5. Pre-compile Patterns (Cache)

<?php
// Good practice: Pre-compile patterns
class RegexCache {
    private static $cache = [];

    public static function get($pattern) {
        if (!isset(self::$cache[$pattern])) {
            self::$cache[$pattern] = $pattern;
        }
        return self::$cache[$pattern];
    }
}

$pattern = RegexCache::get('/\d+/');
?>

Performance Optimization

1. Avoid Repeated Matching

<?php
// Bad practice: Match multiple times
if (preg_match('/\d+/', $text)) {
    preg_match_all('/\d+/', $text, $matches);
}

// Good practice: Match once
preg_match_all('/\d+/', $text, $matches);
if (!empty($matches[0])) {
    // Process results
}
?>

2. Use More Specific Patterns

<?php
// Efficient
$pattern = '/\d{3}-\d{4}-\d{4}/';

// Inefficient
$pattern = '/.+/';
?>

3. Limit Match Scope

<?php
// Good practice: Specify start and end
$pattern = '/^\d+$/';

// Bad practice: Search in entire string
$pattern = '/\d+/';
?>

Common Errors

1. Forgetting to Escape

<?php
// Error: No escape for backslash
$pattern = '/\d+/';

// Correct: Use single quotes
$pattern = '/\d+/';

// Or escape
$pattern = "/\\d+/";
?>

2. Confusing preg_match and preg_match_all

<?php
// Error: Want all matches but used preg_match
preg_match('/\d+/', "1 2 3", $matches);
echo $matches[0];  // Only "1"

// Correct: Use preg_match_all
preg_match_all('/\d+/', "1 2 3", $matches);
print_r($matches[0]);  // ["1", "2", "3"]
?>

3. Incorrectly Using Replacement References

<?php
// Error: Using variable reference in double quotes
$pattern = '/(\d+)/';
$replacement = "$1";  // Might error

// Correct: Use single quotes or escape
$replacement = '$1';
?>

Summary

FunctionPurposeReturn Value
preg_match()Single match0 or 1
preg_match_all()Global matchMatch count
preg_replace()Regex replacementReplaced string
preg_replace_callback()Callback replacementReplaced string
preg_split()Split stringArray
preg_grep()Filter arrayMatched array
preg_filter()Conditional replacementReplaced array

Selection Guide:

  • Validation → preg_match()
  • Extraction → preg_match() or preg_match_all()
  • Simple replacement → preg_replace()
  • Complex replacement → preg_replace_callback()
  • Splitting → preg_split()
  • Filtering arrays → preg_grep()

Master these functions, and you can efficiently handle various text operations in PHP!

Use our online Regex Tester to test PHP regex patterns!


About the Author

The Regex Master Team consists of experienced developers and technical writers dedicated to simplifying regular expressions for everyone. We ensure all patterns are rigorously tested and verified to provide accurate, production-ready solutions.

Try It: Regex Tester

Use our interactive regex tester to experiment with the patterns you learned in this article. Test your regular expressions in real-time and see immediate results.

Loading tester...

Related Articles

C# (.NET) Regular Expressions Classic Cases

Deep dive into C# regular expressions, master Regex class advanced usage and practical application cases.

Read Article

Golang Regex: regexp Package Best Practices

Learn Go language's regexp package, master efficient regex usage techniques and best practices.

Read Article

Java Regular Expressions: Pattern and Matcher Advanced Usage

Master Java's Pattern and Matcher classes, learn advanced regex techniques and best practices.

Read Article

JavaScript Regex Methods: test vs match vs exec

Deep dive into JavaScript regex methods: understand the differences between test, match, and exec, and learn when to use each.

Read Article
R
Regex Master

Your comprehensive guide to mastering regular expressions through tutorials and tools.

Company

  • About Us
  • Contact
  • FAQ

Resources

  • All Articles
  • Popular Tools
  • Sitemap

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Disclaimer

© 2026 Regex Master. All rights reserved.