Categories
PHP

Search and replace with preg_replace()

Learn how to use the preg_replace() function to replace all occurrences of a pattern (regular expression) with replacement and get the modified result.

  1. The preg_replace() function
  2. Using backreferences
    Delete duplicate words
  3. Limit possible replacements
  4. Count the number of replacements done
  5. The preg_filter function

preg_replace()

preg_replace(
    string|array $pattern,
    string|array $replacement,
    string|array $subject,
    int $limit = -1,
    int &$count = null
): string|array|null

The preg_replace() function takes five parameters:

  1. $pattern: The regular expression as a string or a string array to search for.
  2. $replacement: The replacement text to replace any matched text with (string or array of strings).
  3. $subject: The input string or array to search through.
  4. $limit (optional): The maximum possible replacements, default to -1 (no limit).
  5. &$count (optional): If specified, this variable will be filled with the number of replacements done.

The preg_replace() function searches for a pattern in the subject and replaces the subject with something else defined in the $replacement parameter. This function returns an array or string based on the subject parameter, a string returned if the subject parameter is a string and an array returned if the subject parameter is an array.

Example: if the $subject parameter is a string

If the subject is a string and a match is found, then the new subject string will be returned, otherwise, the old string is returned.

<?php
 $subject = 'force, file, fake, fire, wire';
 $pattern = '/f(.*?)e/';
 $replacement = 's$1e';
 $result = preg_replace($pattern, $replacement, $subject);
 echo $result;
 //Prints: sorce, sile, sake, sire, wire

Example: if the $subject parameter is an array

If the subject being searched is an array, then the search and replace is performed on every entry of the subject, and the returned value is an array.

<?php
 //Subject is an array
 $subject = ['force', 'file', 'fake', 'fire', 'wire'];
 $pattern = '/f(.*?)e/';
 $replacement = 's$1e';
 $result = preg_replace($pattern, $replacement, $subject);
 print_r( $result );
 /*Prints:
 Array(
  [0] => sorce
  [1] => sile
  [2] => sake
  [3] => sire
  [4] => wire)*/

Example: $pattern array to perform multiple pattern matches

The preg_replace() function also accepts arrays as both the $pattern and $replacment parameters for multiple pattern matching and replacements. If the replacement is a string and the pattern is an array, all the matched patterns will be replaced in the subject.

<?php
 $subject = ['file', 'fire', 'rock', 'rank'];
 $pattern = ['/f(.*?)e/', '/r(.*?)k/']; 
 $replacement = 's$1e';
 $result = preg_replace($pattern,$replacement,$subject);
 print_r($result);
 /*Array (
    [0] => sile
    [1] => sire
    [2] => soce
    [3] => sane
 )*/

Example: $pattern and $replacement are arrays, perform multiple pattern matches

If both pattern and replacement are arrays, each pattern will be replaced by the replacement counterpart.

<?php
 $subject = ['file', 'fire', 'rock', 'rank'];
 $pattern = ['/f(.*?)e/', '/r(.*?k)/']; 
 $replacement = ['s$1e', 'b$1'];
 $result = preg_replace($pattern,$replacement,$subject);

 print_r($result);
 /*Array (
    [0] => sile
    [1] => sire
    [2] => bock
    [3] => bank
 )*/

If $replacement array elements are less than the $pattern array elements then any extra patterns will be replaced by an empty string.

<?php
 $subject = ['file', 'fire', 'rock', 'rank'];
 $pattern = ['/f(.*?)e/', '/r(.*?k)/']; 
 $replacement = ['s$1e'];
 $result = preg_replace($pattern,$replacement,$subject);

 print_r($result);
 /*Array (
    [0] => sile
    [1] => sire
    [2] => 
    [3] => 
)*/

Backreferences

You can use backreferences within the replacement parameter, just write a dollar $ sign (or backslash \) followed by the reference number. The first parenthesized subpattern number is 1 and the second subpattern number is 2 and so on.

<?php
 $subject = 'a, b, c, d';
 $pattern = '/(a), (b), (c), (d)/';
 $replace = '$4, $3, $2, $1';
 echo preg_replace($pattern, $replace, $subject);
 //d, c, b, a

 # or
 $replace2 = '\4, \3, \2, \1'; 
 echo preg_replace($pattern, $replace2, $subject);
 //d, c, b, a

Example: Using regular expressions to delete duplicate words

You can also use the backreferences within the pattern parameter, just use backslash \ followed by the reference number, for example, \1, \2, and so on. You can not use the dollar sign $ for backreferences ($1, $2, …) within the pattern parameter:

<?php
 $subject = 'Hi Hi, delete delete the the repeated 
             repeated words  new new line line...';
 $pattern = '/\b(\w+)\s+\1/';
 $replace = '\1'; // or use '$1'
 echo preg_replace($pattern, $replace, $subject);
 # Hi, delete the repeated words  new line...

\b is a word boundary, \w is any word character, \s is any whitespace character (space, tab, newline, etc.), and \1 is the reference to capture the match of the first parenthesized subpattern.

Note: Octal ASCII character escaping sequences problem

<?php
 echo "\127";  //Prints: W
 echo '\127';  //Prints: \127
 echo "\\127"; //Prints: \127

If the backreference code is inside the double quotes marks, place an extra backslash before the \1 reference, because PHP translates "\1" as an ASCII character, or use $1 reference in the $replacement parameter (you can not use $ sign for backreferences in the pattern).

<?php
 $subject = 'a, b, c, d';
 $pattern = '/(a), (b), (c), (d)/';
 $replace = "\\4, \\3, \\2, \\1";
 echo preg_replace($pattern, $replace, $subject);
 //d, c, b, a

 $replace2 = "$4, $3, $2, $1";
 echo preg_replace($pattern, $replace2, $subject);
 //d, c, b, a

Use $0 or \0 to include the entire matched pattern in the replacement string:

<?php

 $subject = 'a, b, c, d';
 $pattern = '/(a), (b), (c), (d)/';
 $replace = '\0';
 echo preg_replace($pattern, $replace, $subject);
 //a, b, c, d

  $replace2 = '$0';
 echo preg_replace($pattern, $replace2, $subject);
 //a, b, c, d

Limit replacement in a string

By default, php_replace() function replaces unlimited pattern matches, but you can use the fourth parameter $limit to limit the number of replacements in the subject:

<?php
 //Delete duplicate words
 $subject = 'Hi Hi, delete delete the the repeated 
             repeated words  new new line line...';
 $pattern = '/\b(\w+)\s+\1/';
 $replace = '\1'; // or use '$1'
 $limit   = 3;
 echo preg_replace($pattern, $replace, $subject, $limit);
 /* Hi, delete the repeated 
             repeated words  new new line line...*/

Count how many replacements occurred in the string

Use the fifth parameter $count to count the number of replacements that occurred in the string. If you don’t want to limit the replacement then set the $limit parameter value to -1 (it is the default value). You can also use the named argument for the $count parameter if you don’t want to define the $limit parameter, see the following example:

<?php
 //Delete duplicate words
 $subject = 'Hi Hi, delete delete the the repeated 
             repeated words  new new line line...';
 $pattern = '/\b(\w+)\s+\1/';
 $replace = '\1'; // or use '$1'
 $newSub = preg_replace($pattern, $replace, $subject, -1, $count);

 //OR use named argument for the count parameter
 #$newSub = preg_replace($pattern, $replace, $subject, count:$count);

 echo $count; //Prints 6

preg_filter()

The preg_filter() function works similar to the preg_replace() function, but, if a match were not found in the subject, it returns an empty array if the subject is an array or returns NULL if the subject is a string.

<?php
 $subject = 'Hi, Welcome to BrainBell.com';
 $pattern = '/Website/';
 $replace = 'BrainBell.com';
 $newSub = preg_filter($pattern, $replace, $subject, -1, $count);
 var_dump( $newSub); // NULL
 echo $count; // 0

More Regular Expressions Tutorials: