preg_replace

(PHP 4, PHP 5, PHP 7, PHP 8)

preg_replacePerform a regular expression search and replace

Description

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

Searches subject for matches to pattern and replaces them with replacement.

To match an exact string, rather than a pattern, consider using str_replace() or str_ireplace() instead of this function.

Parameters

pattern

The pattern to search for. It can be either a string or an array with strings.

Several PCRE modifiers are also available.

replacement

The string or an array with strings to replace. If this parameter is a string and the pattern parameter is an array, all patterns will be replaced by that string. If both pattern and replacement parameters are arrays, each pattern will be replaced by the replacement counterpart. If there are fewer elements in the replacement array than in the pattern array, any extra patterns will be replaced by an empty string.

replacement may contain references of the form \n or $n, with the latter form being the preferred one. Every such reference will be replaced by the text captured by the n'th parenthesized pattern. n can be from 0 to 99, and \0 or $0 refers to the text matched by the whole pattern. Opening parentheses are counted from left to right (starting from 1) to obtain the number of the capturing subpattern. Note that backslashes in string literals may require to be escaped.

When working with a replacement pattern where a backreference is immediately followed by another number (i.e.: placing a literal number immediately after a matched pattern), you cannot use the familiar \1 notation for your backreference. \11, for example, would confuse preg_replace() since it does not know whether you want the \1 backreference followed by a literal 1, or the \11 backreference followed by nothing. In this case the solution is to use ${1}1. This creates an isolated $1 backreference, leaving the 1 as a literal.

When using the deprecated e modifier, this function escapes some characters (namely ', ", \ and NULL) in the strings that replace the backreferences. This is done to ensure that no syntax errors arise from backreference usage with either single or double quotes (e.g. 'strlen(\'$1\')+strlen("$2")'). Make sure you are aware of PHP's string syntax to know exactly how the interpreted string will look.

subject

The string or an array with strings to search and replace.

If subject is an array, then the search and replace is performed on every entry of subject, and the return value is an array as well.

If the subject array is associative, keys will be preserved in the returned value.

limit

The maximum possible replacements for each pattern in each subject string. Defaults to -1 (no limit).

count

If specified, this variable will be filled with the number of replacements done.

Return Values

preg_replace() returns an array if the subject parameter is an array, or a string otherwise.

If matches are found, the new subject will be returned, otherwise subject will be returned unchanged or null if an error occurred.

Errors/Exceptions

Using the "\e" modifier is an error; an E_WARNING is emitted in this case.

If the regex pattern passed does not compile to a valid regex, an E_WARNING is emitted.

Examples

Example #1 Using backreferences followed by numeric literals

<?php
$string
= 'April 15, 2003';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}1,$3';
echo
preg_replace($pattern, $replacement, $string);
?>

The above example will output:

April1,2003

Example #2 Using indexed arrays with preg_replace()

<?php
$string
= 'The quick brown fox jumps over the lazy dog.';
$patterns = array();
$patterns[0] = '/quick/';
$patterns[1] = '/brown/';
$patterns[2] = '/fox/';
$replacements = array();
$replacements[2] = 'bear';
$replacements[1] = 'black';
$replacements[0] = 'slow';
echo
preg_replace($patterns, $replacements, $string);
?>

The above example will output:

The bear black slow jumps over the lazy dog.

By ksorting patterns and replacements, we should get what we wanted.

<?php
ksort
($patterns);
ksort($replacements);
echo
preg_replace($patterns, $replacements, $string);
?>

The above example will output:

The slow black bear jumps over the lazy dog.

Example #3 Replacing several values

<?php
$patterns
= array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
'/^\s*{(\w+)}\s*=/');
$replace = array ('\3/\4/\1\2', '$\1 =');
echo
preg_replace($patterns, $replace, '{startDate} = 1999-5-27');
?>

The above example will output:

$startDate = 5/27/1999

Example #4 Strip whitespace

This example strips excess whitespace from a string.

<?php
$str
= 'foo o';
$str = preg_replace('/\s\s+/', ' ', $str);
// This will be 'foo o' now
echo $str;
?>

Example #5 Using the count parameter

<?php
$count
= 0;

echo
preg_replace(array('/\d/', '/\s/'), '*', 'xp 4 to', -1 , $count);
echo
$count; //3
?>

The above example will output:

xp***to
3

Notes

Note:

When using arrays with pattern and replacement, the keys are processed in the order they appear in the array. This is not necessarily the same as the numerical index order. If you use indexes to identify which pattern should be replaced by which replacement, you should perform a ksort() on each array prior to calling preg_replace().

Note:

When both pattern and replacement are arrays, matching rules will operate sequentially. That is, the second pattern/replacement pair will operate on the string that results from the first pattern/replacement pair, not the original string. If you want to simulate replacements operating in parallel, such as swapping two values, replace one pattern by an intermediary placeholder, then in a later pair replace that intermediary placeholder with the desired replacement.

<?php
$p
= array('/a/', '/b/', '/c/');
$r = array('b', 'c', 'd');
print_r(preg_replace($p, $r, 'a'));
// prints d
?>

See Also

add a note add a note

User Contributed Notes 50 notes

up
706
arkani at iol dot pt
15 years ago
Because i search a lot 4 this:

The following should be escaped if you are trying to match that character

\ ^ . $ | ( ) [ ]
* + ? { } ,

Special Character Definitions
\ Quote the next metacharacter
^ Match the beginning of the line
. Match any character (except newline)
$ Match the end of the line (or before newline at the end)
| Alternation
() Grouping
[] Character class
* Match 0 or more times
+ Match 1 or more times
? Match 1 or 0 times
{n} Match exactly n times
{n,} Match at least n times
{n,m} Match at least n but not more than m times
More Special Character Stuff
\t tab (HT, TAB)
\n newline (LF, NL)
\r return (CR)
\f form feed (FF)
\a alarm (bell) (BEL)
\e escape (think troff) (ESC)
\033 octal char (think of a PDP-11)
\x1B hex char
\c[ control char
\l lowercase next char (think vi)
\u uppercase next char (think vi)
\L lowercase till \E (think vi)
\U uppercase till \E (think vi)
\E end case modification (think vi)
\Q quote (disable) pattern metacharacters till \E
Even More Special Characters
\w Match a "word" character (alphanumeric plus "_")
\W Match a non-word character
\s Match a whitespace character
\S Match a non-whitespace character
\d Match a digit character
\D Match a non-digit character
\b Match a word boundary
\B Match a non-(word boundary)
\A Match only at beginning of string
\Z Match only at end of string, or before newline at the end
\z Match only at end of string
\G Match only where previous m//g left off (works only with /g)
up
80
hello at weblap dot ro
14 years ago
Post slug generator, for creating clean urls from titles.
It works with many languages.

<?php
function remove_accent($str)
{
 
$a = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', 'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', 'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ', 'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', 'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', 'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', 'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ', 'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', 'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', 'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ');
 
$b = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
  return
str_replace($a, $b, $str);
}

function
post_slug($str)
{
  return
strtolower(preg_replace(array('/[^a-zA-Z0-9 -]/', '/[ -]+/', '/^-|-$/'),
  array(
'', '-', ''), remove_accent($str)));
}
?>

Example: post_slug(' -Lo#&@rem  IPSUM //dolor-/sit - amet-/-consectetur! 12 -- ')
will output: lorem-ipsum-dolor-sit-amet-consectetur-12
up
3
Anonymous
3 years ago
Warning: craiga's function escape_backreference() is incomplete (doesn't escape '\0' nor '${0}').

To escape any potential backreferences in a replacement variable, use addcslashes() for backslash and dollar characters:

<?php
// $replacement may contain sequences like \0, $0 or ${0}
echo preg_replace($pattern, addcslashes($replacement, '\\$'), $subject);
?>
up
34
denis_truffaut a t hotmail d o t com
12 years ago
If you want to catch characters, as well european, russian, chinese, japanese, korean of whatever, just :
- use mb_internal_encoding('UTF-8');
- use preg_replace('`...`u', '...', $string) with the u (unicode) modifier

For further information, the complete list of preg_* modifiers could be found at :
http://php.net/manual/en/reference.pcre.pattern.modifiers.php
up
6
dani dot church at gmail dot youshouldknowthisone
17 years ago
Note that it is in most cases much more efficient to use preg_replace_callback(), with a named function or an anonymous function created with create_function(), instead of the /e modifier.  When preg_replace() is called with the /e modifier, the interpreter must parse the replacement string into PHP code once for every replacement made, while preg_replace_callback() uses a function that only needs to be parsed once.
up
9
marcin at pixaltic dot com
15 years ago
<?php
   
//:::replace with anything that you can do with searched string:::
    //Marcin Majchrzak
    //pixaltic.com
   
   
$c = "2 4 8";
    echo (
$c); //display:2 4 8

   
$cp = "/(\d)\s(\d)\s(\d)/e"; //pattern
   
$cr = "'\\3*\\2+\\1='.(('\\3')*('\\2')+('\\1'))"; //replece
   
$c = preg_replace($cp, $cr, $c);
    echo (
$c); //display:8*4+2=34
?>
up
5
rob at ubrio dot us
16 years ago
Also worth noting is that you can use array_keys()/array_values() with preg_replace like:

<?php
$subs
= array(
 
'/\[b\](.+)\[\/b\]/Ui' => '<strong>$1</strong>',
 
'/_(.+)_/Ui' => '<em>$1</em>'
 
...
  ...
);

$raw_text = '[b]this is bold[/b] and this is _italic!_';

$bb_text = preg_replace(array_keys($subs), array_values($subs), $raw_text);
?>
up
13
akniep at rayo dot info
15 years ago
preg_replace (and other preg-functions) return null instead of a string when encountering problems you probably did not think about!
-------------------------

It may not be obvious to everybody that the function returns NULL if an error of any kind occurres. An error I happen to stumple about quite often was the back-tracking-limit:
http://de.php.net/manual/de/pcre.configuration.php
#ini.pcre.backtrack-limit

When working with HTML-documents and their parsing it happens that you encounter documents that have a length of over 100.000 characters and that may lead to certain regular-expressions to fail due the back-tracking-limit of above.

A regular-expression that is ungreedy ("U", http://de.php.net/manual/de/reference.pcre.pattern.modifiers.php) often does the job, but still: sometimes you just need a greedy regular expression working on long strings ...

Since, an unhandled return-value of NULL usually creates a consecutive error in the application with unwanted and unforeseen consequences, I found the following solution to be quite helpful and at least save the application from crashing:

<?php

$string_after
= preg_replace( '/some_regexp/', "replacement", $string_before );

// if some error occurred we go on working with the unchanged original string
if (PREG_NO_ERROR !== preg_last_error())
{
   
$string_after = $string_before;
   
   
// put email-sending or a log-message here
} //if

// free memory
unset( $string_before );

?>

You may or should also put a log-message or the sending of an email into the if-condition in order to get informed, once, one of your regular-expressions does not have the effect you desired it to have.
up
5
Garrett Albright
8 years ago
It may be useful to note that if you pass an associative array as the $replacement parameter, the keys are preserved.

<?php
$replaced
= preg_replace('/foo/', 'bar', ['first' => 'foobar', 'second' => 'barfoo']);
// $replaced is now ['first' => 'barbar', 'second' => 'barbar'].
?>
up
12
spamthishard at wtriple dot com
10 years ago
If you want to replace only the n-th occurrence of $pattern, you can use this function:

<?php

function preg_replace_nth($pattern, $replacement, $subject, $nth=1) {
    return
preg_replace_callback($pattern,
        function(
$found) use (&$pattern, &$replacement, &$nth) {
               
$nth--;
                if (
$nth==0) return preg_replace($pattern, $replacement, reset($found) );
                return
reset($found);
        },
$subject,$nth  );
}

echo
preg_replace_nth("/(\w+)\|/", '${1} is the 4th|', "|aa|b|cc|dd|e|ff|gg|kkk|", 4);

?>

this outputs |aa|b|cc|dd is the 4th|e|ff|gg|kkk|
backreferences are accepted in $replacement
up
9
Alexey Lebedev
17 years ago
Wasted several hours because of this:

<?php
$str
='It&#039;s a string with HTML entities';
preg_replace('~&#(\d+);~e', 'code2utf($1)', $str);
?>

This code must convert numeric html entities to utf8. And it does with a little exception. It treats wrong codes starting with &#0

The reason is that code2utf will be called with leading zero, exactly what the pattern matches - code2utf(039).
And it does matter! PHP treats 039 as octal number.
Try <?php print(011); ?>

Solution:
<?php preg_replace('~&#0*(\d+);~e', 'code2utf($1)', $str); ?>
up
7
cincodenada at gmail dot dot dot com
11 years ago
There seems to be some confusion over how greediness works.  For those familiar with Regular Expressions in other languages, particularly Perl: it works like you would expect, and as documented.  Greedy by default, un-greedy if you follow a quantifier with a question mark.

There is a PHP/PCRE-specific U pattern modifier that flips the greediness, so that quantifiers are by default un-greedy, and become greedy if you follow the quantifier with a question mark: http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

To make things clear, a series of examples:

<?php

$preview
= "a bunch of stuff <code>this that</code> and more stuff <code>with a second code block</code> then extra at the end";

$preview_default = preg_replace('/<code>(.*)<\/code>/is', "<code class=\"prettyprint\">$1</code>", $preview);
$preview_manually_ungreedy = preg_replace('/<code>(.*?)<\/code>/is', "<code class=\"prettyprint\">$1</code>", $preview);

$preview_U_default = preg_replace('/<code>(.*)<\/code>/isU', "<code class=\"prettyprint\">$1</code>", $preview);
$preview_U_manually_greedy = preg_replace('/<code>(.*?)<\/code>/isU', "<code class=\"prettyprint\">$1</code>", $preview);

echo
"Default, no ?: $preview_default\n";
echo
"Default, with ?: $preview_manually_ungreedy\n";
echo
"U flag, no ?: $preview_U_default\n";
echo
"U flag, with ?: $preview_U_manually_greedy\n";

?>

Results in this:

Default, no ?: a bunch of stuff <code class="prettyprint">this that</code> and more stuff <code>with a second code block</code> then extra at the end
Default, with ?: a bunch of stuff <code class="prettyprint">this that</code> and more stuff <code class="prettyprint">with a second code block</code> then extra at the end
U flag, no ?: a bunch of stuff <code class="prettyprint">this that</code> and more stuff <code class="prettyprint">with a second code block</code> then extra at the end
U flag, with ?: a bunch of stuff <code class="prettyprint">this that</code> and more stuff <code>with a second code block</code> then extra at the end

As expected: greedy by default, ? inverts it to ungreedy.  With the U flag, un-greedy by default, ? makes it greedy.
up
3
sternkinder at gmail dot com
16 years ago
From what I can see, the problem is, that if you go straight and substitute all 'A's wit 'T's you can't tell for sure which 'T's to substitute with 'A's afterwards. This can be for instance solved by simply replacing all 'A's by another character (for instance '_' or whatever you like), then replacing all 'T's by 'A's, and then replacing all '_'s (or whatever character you chose) by 'A's:

<?php
$dna
= "AGTCTGCCCTAG";
echo
str_replace(array("A","G","C","T","_","-"), array("_","-","G","A","T","C"), $dna); //output will be TCAGACGGGATC
?>

Although I don't know how transliteration in perl works (though I remember that is kind of similar to the UNIX command "tr") I would suggest following function for "switching" single chars:

<?php
function switch_chars($subject,$switch_table,$unused_char="_") {
    foreach (
$switch_table as $_1 => $_2 ) {
       
$subject = str_replace($_1,$unused_char,$subject);
       
$subject = str_replace($_2,$_1,$subject);
       
$subject = str_replace($unused_char,$_2,$subject);
    }
    return
$subject;
}

echo
switch_chars("AGTCTGCCCTAG", array("A"=>"T","G"=>"C")); //output will be TCAGACGGGATC
?>
up
6
nospam at probackup dot nl
13 years ago
Warning: a common made mistake in trying to remove all characters except numbers and letters from a string, is to use code with a regex similar to preg_replace('[^A-Za-z0-9_]', '', ...). The output goes in an unexpected direction in case your input contains two double quotes.

echo preg_replace('[^A-Za-z0-9_]', '', 'D"usseldorfer H"auptstrasse')

D"usseldorfer H"auptstrasse

It is important to not forget a leading an trailing forward slash in the regex:

echo preg_replace('/[^A-Za-z0-9_]/', '', 'D"usseldorfer H"auptstrasse')

Dusseldorfer Hauptstrasse

PS An alternative is to use preg_replace('/\W/', '', $t) for keeping all alpha numeric characters including underscores.
up
9
logofero at gmail dot com
8 years ago
Why not offset parameter to replace the string? It would be helpful

example:

mixed preg_replace (mixed $pattern, mixed $replacement, mixed $subject [, int $limit = -1 [, int & $count [, int $offset = 0]]])

1 $pattern
2 $replacement
3 $subject
4 $limit
5 $count
6 $offset <- it is planned?
up
6
Terminux (dot) anonymous at gmail
13 years ago
This function will strip all the HTML-like content in a string.
I know you can find a lot of similar content on the web, but this one is simple, fast and robust. Don't simply use the built-in functions like strip_tags(), they dont work so good.

Careful however, this is not a correct validation of a string ; you should use additional functions like mysql_real_escape_string and filter_var, as well as custom tests before putting a submission into your database.

<?php

$html
= <<<END
<div id="function.preg-split" class="refentry"> Bonjour1 \t
<div class="refnamediv"> Bonjour2 \t
<h1 class="refname">Bonjour3 \t</h1>
<h1 class=""">Bonjour4 \t</h1>
<h1 class="*%1">Bonjour5 \t</h1>
<body>Bonjour6 \t<//body>>
</ body>Bonjour7 \t<////        body>>
<
a href="image.php" alt="trans" /        >
some leftover text...
     < DIV class=noCompliant style = "text-align:left;" >
... and some other ...
< dIv > < empty>  </ empty>
  <p> This is yet another text <br  >
     that wasn't <b>compliant</b> too... <br   />
     </p>
<div class="noClass" > this one is better but we don't care anyway </div ><P>
    <input   type= "text"  name ='my "name' value  = "nothin really." readonly>
end of paragraph </p> </Div>   </div>   some trailing text
END;

// This echoes correctly all the text that is not inside HTML tags
$html_reg = '/<+\s*\/*\s*([A-Z][A-Z0-9]*)\b[^>]*\/*\s*>+/i';
echo
htmlentities( preg_replace( $html_reg, '', $html ) );

// This extracts only a small portion of the text
echo htmlentities(strip_tags($html));

?>
up
1
mdrisser at gmail dot com
15 years ago
An alternative to the method suggested by sheri is to remember that the regex modifier '$' only looks at the end of the STRING, the example given is a single string consisting of multiple lines.

Try:
<?php
// Following is 1 string containing 3 lines
$s = "Testing, testing.\r\n"
  
. "Another testing line.\r\n"
  
. "Testing almost done.";

echo
preg_replace('/\.\\r\\n/m', '@\r\n', $s);
?>

This results in the string:
Testing, testing@\r\nAnother testing line@\r\nTesting almost done.
up
7
hvishnu999 at gmail dot com
12 years ago
To covert a string to SEO friendly, do this:

<?php
$realname
= "This is the string to be made SEO friendly!"

$seoname = preg_replace('/\%/',' percentage',$realname);
$seoname = preg_replace('/\@/',' at ',$seoname);
$seoname = preg_replace('/\&/',' and ',$seoname);
$seoname = preg_replace('/\s[\s]+/','-',$seoname);    // Strip off multiple spaces
$seoname = preg_replace('/[\s\W]+/','-',$seoname);    // Strip off spaces and non-alpha-numeric
$seoname = preg_replace('/^[\-]+/','',$seoname); // Strip off the starting hyphens
$seoname = preg_replace('/[\-]+$/','',$seoname); // // Strip off the ending hyphens
$seoname = strtolower($seoname);

echo
$seoname;
?>

This will print: this-is-the-string-to-be-made-seo-friendly
up
1
bublifuk at mailinator dot com
5 years ago
A delimiter can be any ASCII non-alphanumeric, non-backslash, non-whitespace character:  !"#$%&'*+,./:;=?@^_`|~-  and  ({[<>]})
up
3
David
15 years ago
Take care when you try to strip whitespaces out of an UTF-8 text. Using something like:

<?php
$text
= preg_replace( "{\s+}", ' ', $text );
?>

brokes in my case the letter à which is hex c3a0. But a0 is a whitespace. So use

<?php
$text
= preg_replace( "{[ \t]+}", ' ', $text );
?>

to strip all spaces and tabs, or better, use a multibyte function like mb_ereg_replace.
up
5
craiga at craiga dot id dot au
12 years ago
If there's a chance your replacement text contains any strings such as "$0.95", you'll need to escape those $n backreferences:

<?php
function escape_backreference($x)
{
    return
preg_replace('/\$(\d)/', '\\\$$1', $x);
}
?>
up
2
ulf dot reimers at tesa dot com
16 years ago
Hi,

as I wasn't able to find another way to do this, I wrote a function converting any UTF-8 string into a correct NTFS filename (see http://en.wikipedia.org/wiki/Filename).

<?php
function strToNTFSFilename($string)
{
 
$reserved = preg_quote('\/:*?"<>', '/');
  return
preg_replace("/([\\x00-\\x1f{$forbidden}])/e", "_", $string);
}
?>

It converts all control characters and filename characters which are reserved by Windows ('\/:*?"<>') into an underscore.
This way you can safely create an NTFS filename out of any UTF-8 string.
up
2
akarmenia at gmail dot com
12 years ago
[Editor's note: in this case it would be wise to rely on the preg_quote() function instead which was added for this specific purpose]

If your replacement string has a dollar sign or a backslash. it may turn into a backreference accidentally! This will fix it.

I want to replace 'text' with '$12345' but this becomes a backreference to $12 (which doesn't exist) and then it prints the remaining '34'. The function down below will return a string that escapes the backreferences.

OUTPUT:
string(8) "some 345"
string(11) "some \12345"
string(8) "some 345"
string(11) "some $12345"

<?php

$a
= 'some text';

// Either of these will backreference and fail
$b1 = '\12345'; // Should be '\\12345' to avoid backreference
$b2 = '$12345'; // Should be '\$12345' to avoid backreference

$d = array($b1, $b2);

foreach (
$d as $b) {
   
$result1 = preg_replace('#(text)#', $b, $a); // Fails
   
var_dump($result1);
   
$result2 = preg_replace('#(text)#', preg_escape_back($b), $a); // Succeeds
   
var_dump($result2);
}

// Escape backreferences from string for use with regex
function preg_escape_back($string) {
   
// Replace $ with \$ and \ with \\
   
$string = preg_replace('#(?<!\\\\)(\\$|\\\\)#', '\\\\$1', $string);
    return
$string;
}

?>
up
1
mike dot hayward at mikeyskona dot co dot uk
16 years ago
Hi.
Not sure if this will be a great help to anyone out there, but thought i'd post just in case.
I was having an Issue with a project that relied on $_SERVER['REQUEST_URI']. Obviously this wasn't working on IIS.
(i am using mod_rewrite in apache to call up pages from a database and IIS doesn't set REQUEST_URI). So i knocked up this simple little preg_replace to use the query string set by IIS when redirecting to a PHP error page.

<?php
//My little IIS hack :)
if(!isset($_SERVER['REQUEST_URI'])){
 
$_SERVER['REQUEST_URI'] = preg_replace( '/404;([a-zA-Z]+:\/\/)(.*?)\//i', "/" , $_SERVER['QUERY_STRING'] );
}
?>

Hope this helps someone else out there trying to do the same thing :)
up
2
timitheenchanter
12 years ago
If you have issues where preg_replace returns an empty string, please take a look at these two ini parameters:

pcre.backtrack_limit
pcre.recursion_limit

The default is set to 100K.  If your buffer is larger than this, look to increase these two values.
up
1
Nibbels
9 years ago
I have been filtering every userinput with preg_replace since 6 Years now and nothing happened. I am running PHP 5.6.6 and because of historical reasons I still do not use mysqli.
Now i noticed that this filter [^0-9a-zA-Z_ -|:\.] won't filter anything from a Sleeping-Hack-String like `%' AnD sLeep(3) ANd '1%`:

preg_replace ( '/[^0-9a-zA-Z_ -|:\.]/', '', "%' AnD sLeep(3) ANd '1%" );

The reason is, that the fourth Minus has to be escaped!
Fix: [^0-9a-zA-Z_ \-|:\.]

I tell you because I did not know this and I am pretty sure btw. maybe in older versions of PHP some did not have to escape this minus. Those hacks did not work in the old days, because formerly I have been testing against this.

Greetings
up
2
me at perochak dot com
13 years ago
If you would like to remove a tag along with the text inside it then use the following code.

<?php
preg_replace
('/(<tag>.+?)+(<\/tag>)/i', '', $string);
?>

example
<?php $string='<span class="normalprice">55 PKR</span>'; ?>

<?php
$string
= preg_replace('/(<span class="normalprice">.+?)+(<\/span>)/i', '', $string);
?>

This will results a null or empty string.

<?php
$string
='My String <span class="normalprice">55 PKR</span>';

$string = preg_replace('/(<span class="normalprice">.+?)+(<\/span>)/i', '', $string);
?>

This will results a " My String"
up
2
anyvie at devlibre dot fr
12 years ago
A variable can handle a huge quantity of data but preg_replace can't.

Example :
<?php
$url
= "ANY URL WITH LOTS OF DATA";

// We get all the data into $data
$data = file_get_contents($url);

// We just want to keep the content of <head>
$head = preg_replace("#(.*)<head>(.*?)</head>(.*)#is", '$2', $data);
?>

$head can have the desired content, or be empty, depends on the length of $data.

For this application, just add :
$data = substr($data, 0, 4096);
before using preg_replace, and it will work fine.
up
1
nik at rolls dot cc
11 years ago
To split Pascal/CamelCase into Title Case (for example, converting descriptive class names for use in human-readable frontends), you can use the below function:

<?php
function expandCamelCase($source) {
  return
preg_replace('/(?<!^)([A-Z][a-z]|(?<=[a-z])[^a-z]|(?<=[A-Z])[0-9_])/', ' $1', $source);
}
?>

Before:
  ExpandCamelCaseAPIDescriptorPHP5_3_4Version3_21Beta
After:
  Expand Camel Case API Descriptor PHP 5_3_4 Version 3_21 Beta
up
2
da_pimp2004_966 at hotmail dot com
15 years ago
A simple BB like thing..

<?php
function AddBB($var) {
       
$search = array(
               
'/\[b\](.*?)\[\/b\]/is',
               
'/\[i\](.*?)\[\/i\]/is',
               
'/\[u\](.*?)\[\/u\]/is',
               
'/\[img\](.*?)\[\/img\]/is',
               
'/\[url\](.*?)\[\/url\]/is',
               
'/\[url\=(.*?)\](.*?)\[\/url\]/is'
               
);

       
$replace = array(
               
'<strong>$1</strong>',
               
'<em>$1</em>',
               
'<u>$1</u>',
               
'<img src="$1" />',
               
'<a href="$1">$1</a>',
               
'<a href="$1">$2</a>'
               
);

       
$var = preg_replace ($search, $replace, $var);
        return
$var;
}
?>
up
1
dyer85 at gmail dot com
15 years ago
There seems to be some unexpected behavior when using the /m modifier when the line terminators are win32 or mac format.

If you have a string like below, and try to replace dots, the regex won't replace correctly:

<?php
$s
= "Testing, testing.\r\n"
  
. "Another testing line.\r\n"
  
. "Testing almost done.";

echo
preg_replace('/\.$/m', '.@', $s); // only last . replaced
?>

The /m modifier doesn't seem to work properly when CRLFs or CRs are used. Make sure to convert line endings to LFs (*nix format) in your input string.
up
1
Michael W
15 years ago
For filename tidying I prefer to only ALLOW certain characters rather than converting particular ones that we want to exclude. To this end I use ...

<?php
  $allowed
= "/[^a-z0-9\\040\\.\\-\\_\\\\]/i";
 
preg_replace($allowed,"",$str));
?>

Allows letters a-z, digits, space (\\040), hyphen (\\-), underscore (\\_) and backslash (\\\\), everything else is removed from the string.
up
1
php-comments-REMOVE dot ME at dotancohen dot com
16 years ago
Below is a function for converting Hebrew final characters to their
normal equivelants should they appear in the middle of a word.
The /b argument does not treat Hebrew letters as part of a word,
so I had to work around that limitation.

<?php

$text
="עברית מבולגנת";

function
hebrewNotWordEndSwitch ($from, $to, $text) {
  
$text=
   
preg_replace('/'.$from.'([א-ת])/u','$2'.$to.'$1',$text);
   return
$text;
}

do {
  
$text_before=$text;
  
$text=hebrewNotWordEndSwitch("ך","כ",$text);
  
$text=hebrewNotWordEndSwitch("ם","מ",$text);
  
$text=hebrewNotWordEndSwitch("ן","נ",$text);
  
$text=hebrewNotWordEndSwitch("ף","פ",$text);
  
$text=hebrewNotWordEndSwitch("ץ","צ",$text);
}   while (
$text_before!=$text );

print
$text; // עברית מסודרת!

?>

The do-while is necessary for multiple instances of letters, such
as "אנני" which would start off as "אןןי". Note that there's still the
problem of acronyms with gershiim but that's not a difficult one
to solve. The code is in use at http://gibberish.co.il which you can
use to translate wrongly-encoded Hebrew, transliterize, and some
other Hebrew-related functions.

To ensure that there will be no regular characters at the end of a
word, just convert all regular characters to their final forms, then
run this function. Enjoy!
up
1
Ducktales
4 years ago
To replace double whitespace by a single space character in a sentence you need to use the \h modifier. It stands for horizontal whitespace. The more common \s modifier includes vertical whitespace such as line breaks, which is not good for saving paragraphs.

Additionally, since most of todays code works with unicode strings you need to add the /u unicode modifier. I tried to replace four sequential normal spaces by one hyphen character resulting in '- - ' instead of '-'. I don't know why it works this way.

<?php
// Replace one or more horizontal white spaces
// of any kind by one normal space character
$str = preg_replace ('/\h+/u', ' ', $str);
?>
up
0
Anonymous
3 years ago
Note that the replacement string using the ${n} notation for a group identifier (rather than the $n notation) must be in a SINGLE quoted string:

$replacement = '${1}1,$3'; // Correct - Single Quoted
$replacement = "${1}1,$3"; // Incorrect - Double Quoted
$replacement = "$1 one , $3"; // Correct - Double Quoted but with $n notation.

This might sneak up on you, because it is not an error to use "${1}".  The double quotes allow a string that contains variable interpolation, and the braces make the variable a PHP "Variable-Variable". In the above example the undefined ${1} will evaluate to NULL rather than the replaced string. Valid PHP, but not what you wanted.
up
-1
mail at johanvandemerwe dot nl
4 years ago
Sample for replacing bracketed short-codes

The used short-codes are purely used for educational purposes for they could be shorter as in 'italic' to 'i' or 'bold' to 'b'.

Sample text
----
This sample shows how to have [italic]italic[/italic], [bold]bold[/bold] and [underline]underlined[/underline] and [strikethrough]striked[/striketrhough] text.

with this function:

<?php
function textDecoration($html)
{
   
$patterns = [
       
'/\[(italic)\].*?\[\/\1\] ?/',
       
'/\[(bold)\].*?\[\/\1\] ?/',
       
'/\[(underline)\].*?\[\/\1\] ?/'
   
];

   
$replacements = [
       
'<i>$1</i>',
       
'<strong>$1</strong>',
       
'<u>$1</u>'
   
];

    return
preg_replace($patterns, $replacements, $html);
}

$html = textDecoration($html);

echo
$html; // or return
?>

results in:
----
This sample shows how to have <i>italic</i>, <b>bold</b> and <u>underlined</u> and [strikethrough]striked[/striketrhough] text.

Notice!
There is no [strikethrough]striked[/striketrhough] fallback in the patterns and replacements array
up
1
willbrownsberger at gmail dot com
5 years ago
Worth knowing:  When arrays of patterns and replacements are provided, they are executed in the order they appear in the array -- so later array elements can act on the results of earlier array elements.

For example:

<?php

echo preg_replace(
    array(
'#cat#', '#dog#', '#eel#', '#snowman#' ),
    array( 
'dog1', 'eel2', 'snowman3', 'monster4' ),
   
'the good cat and the bad dog wandered on the beach'

);

/* result: the good monster4321 and the bad monster432 wandered on the beach
*/
up
0
chrisbloom7 at gmail dot com
5 years ago
Note that when given array arguments the replacement happens in sequence:

<?php
$p
= array('/a/', '/b/', '/c/');
$r = array('b', 'c', 'd');
print_r(preg_replace($p, $r, 'a'));
// => d
?>
up
0
creating SEO friendly Strings
6 years ago
<?php

/**
  * prepares a string optimized for SEO
  * @see https://blog.ueffing.net/post/2016/03/14/string-seo-optimieren-creating-seo-friendly-url/
  * @param String $string
  * @return String $string SEO optimized String
  */
function seofy ($sString = '')
{
   
$sString = preg_replace('/[^\\pL\d_]+/u', '-', $sString);
   
$sString = trim($sString, "-");
   
$sString = iconv('utf-8', "us-ascii//TRANSLIT", $sString);
   
$sString = strtolower($sString);
   
$sString = preg_replace('/[^-a-z0-9_]+/', '', $sString);

    return
$sString;
}

// Example
seofy('Straßenfest in München'); // => strassenfest-in-muenchen
seofy('José Ignacio López de Arriortúa'); // => jose-ignacio-lopez-de-arriortua

?>

The function seofy () creates a SEO friendly version from a string. Umlauts and other letters not contained in the ASCII character set are either reduced to the basic form equivalent (e. g.: é becomes e and ú wid u) or completely converted (e. g. ß becomes ss and ü becomes ue).

On the one hand this succeeds because the php function preg_replace performs the replacement by means of unicode - Unicode Regular Expressions - and on the other hand because an approximate translation is attempted by means of the php function iconv with the TRANSLIT option.

Quote php. net about iconv and TRANSLIT:
"If you append the character string //TRANSLIT to out_charset, transliteration is activated. This means that a character that cannot be displayed in the target character set can be approximated with one or more similar-looking characters.[…]"

Source:
https://blog.ueffing.net/post/2016/03/14/string-seo-optimieren-creating-seo-friendly-url/
up
0
natan dot jesussouza at gmail dot com
6 years ago
$firstname = htmlspecialchars($_POST['campo']);
$firstname = preg_replace("/[^a-zA-Z0-9]/", "", $firstname, -1, $count_fn);

// $count_fn conta quantos caracteres foram mudados.
// $firstname variavel que captura o input
up
0
helia at gmail dot com
8 years ago
$pattern='/(09(1|2|3)\d{8})/';
$string ="n:09138660959 nu: 09371313317 nu:09211313317 n: 09393026988nu:09193472840nnu:09211313317nu:09211313317nu:09121772890";
$replacements='($1 code $2)';
echo  preg_replace($pattern, $replacements, $string);
up
0
Jeroen
9 years ago
Hello there,
I would like to share a regex (PHP) sniplet of code
I wrote (2012) for myself it is also being used in the
Yerico sriptmerge plugin for joomla marked as simple code..
To  compress javascript code and remove all comments from it.
It also works with mootools It is fast...
(in compairison to other PHP solutions) and does not damage the
Javascript it self and it resolves lots of comment removal isseus.

//START Remove comments.

   $buffer = str_replace('/// ', '///', $buffer);       
   $buffer = str_replace(',//', ', //', $buffer);
   $buffer = str_replace('{//', '{ //', $buffer);
   $buffer = str_replace('}//', '} //', $buffer);
   $buffer = str_replace('*//*', '*/  /*', $buffer);
   $buffer = str_replace('/**/', '/*  */', $buffer);
   $buffer = str_replace('*///', '*/ //', $buffer);
   $buffer = preg_replace("/\/\/.*\n\/\/.*\n/", "", $buffer);
   $buffer = preg_replace("/\s\/\/\".*/", "", $buffer);
   $buffer = preg_replace("/\/\/\n/", "\n", $buffer);
   $buffer = preg_replace("/\/\/\s.*.\n/", "\n  \n", $buffer);
   $buffer = preg_replace('/\/\/w[^w].*/', '', $buffer);
   $buffer = preg_replace('/\/\/s[^s].*/', '', $buffer);
   $buffer = preg_replace('/\/\/\*\*\*.*/', '', $buffer);
   $buffer = preg_replace('/\/\/\*\s\*\s\*.*/', '', $buffer);
   $buffer = preg_replace('/[^\*]\/\/[*].*/', '', $buffer);
   $buffer = preg_replace('/([;])\/\/.*/', '$1', $buffer);
   $buffer = preg_replace('/((\r)|(\n)|(\R)|([^0]1)|([^\"]\s*\-))(\/\/)(.*)/', '$1', $buffer);
   $buffer = preg_replace("/([^\*])[\/]+\/\*.*[^a-zA-Z0-9\s\-=+\|!@#$%^&()`~\[\]{};:\'\",<.>?]/", "$1", $buffer);
  $buffer = preg_replace("/\/\*/", "\n/*dddpp", $buffer);
  $buffer = preg_replace('/((\{\s*|:\s*)[\"\']\s*)(([^\{\};\"\']*)dddpp)/','$1$4', $buffer);
  $buffer = preg_replace("/\*\//", "xxxpp*/\n", $buffer);
  $buffer = preg_replace('/((\{\s*|:\s*|\[\s*)[\"\']\s*)(([^\};\"\']*)xxxpp)/','$1$4', $buffer);
  $buffer = preg_replace('/([\"\'])\s*\/\*/', '$1/*', $buffer);
  $buffer = preg_replace('/(\n)[^\'"]?\/\*dddpp.*?xxxpp\*\//s', '', $buffer);
  $buffer = preg_replace('/\n\/\*dddpp([^\s]*)/', '$1', $buffer);
  $buffer = preg_replace('/xxxpp\*\/\n([^\s]*)/', '*/$1', $buffer);
  $buffer = preg_replace('/xxxpp\*\/\n([\"])/', '$1', $buffer);
  $buffer = preg_replace('/(\*)\n*\s*(\/\*)\s*/', '$1$2$3', $buffer);
  $buffer = preg_replace('/(\*\/)\s*(\")/', '$1$2', $buffer);
  $buffer = preg_replace('/\/\*dddpp(\s*)/', '/*', $buffer);
  $buffer = preg_replace('/\n\s*\n/', "\n", $buffer);
  $buffer = preg_replace("/([^\'\"]\s*)<!--.*-->(?!(<\/div>)).*/","$1", $buffer);
  $buffer = preg_replace('/([^\n\w\-=+\|!@#$%^&*()`~\[\]{};:\'",<.>\/?\\\\])(\/\/)(.*)/', '$1', $buffer);

//END Remove comments.   

//START Remove all whitespaces

  $buffer = preg_replace('/\s+/', ' ', $buffer);
  $buffer = preg_replace('/\s*(?:(?=[=\-\+\|%&\*\)\[\]\{\};:\,\.\<\>\!\@\#\^`~]))/', '', $buffer);
  $buffer = preg_replace('/(?:(?<=[=\-\+\|%&\*\)\[\]\{\};:\,\.\<\>\?\!\@\#\^`~]))\s*/', '', $buffer);
  $buffer = preg_replace('/([^a-zA-Z0-9\s\-=+\|!@#$%^&*()`~\[\]
{};:\'",<.>\/?])\s+([^a-zA-Z0-9\s\-=+\|!@#$%^&*()`~\[\]
{};:\'",<.>\/?])/', '$1$2', $buffer);

//END Remove all whitespaces

I am off coarse not a programmer just wanted to
make the plugin work like i wanted it to....
(NOTE:
For the webmaster sorry I posted this in the wrong topic before...)
up
0
Dustin
10 years ago
Matching substrings where the match can exist at the end of the string was non-intuitive to me.

I found this because:
strtotime() interprets 'mon' as 'Monday', but Postgres uses interval types that return short names by default, e.g. interval '1 month' returns as '1 mon'.

I used something like this:

$str = "mon month monday Mon Monday Month MONTH MON";
$strMonth = preg_replace('~(mon)([^\w]|$)~i', '$1th$2', $str);
echo "$str\n$strMonth\n";

//to output:
mon month monday Mon Monday Month MONTH MON
month month monday Month Monday Month MONTH MONth
up
0
sreekanth at outsource-online dot net
12 years ago
if your intention to code and decode mod_rewrite urls and handle it with php and mysql ,this should work

to convert to url
$url = preg_replace('/[^A-Za-z0-9_-]+/', '-', $string);

And to check in mysql with the url value,use the same expression discounting '-'.
first replace the url value  with php using preg_replace  and use with mysql REGEXP

$sql = "select * from table where fieldname_to_check REGEXP '".preg_replace("/-+/",'[^A-Za-z0-9_]+',$url)."'"
up
0
someuser at dot dot com
12 years ago
Replacement of line numbers, with replacement limit per line.

Solution that worked for me.
I have a file with tasks listed each starting from number, and only starting number should be removed because forth going text has piles of numbers to be omitted.

56 Patient A of 46 years suffering ... ...
57 Newborn of 26 weeks was ...
58 Jane, having age 18 years recollects onsets of ...
...
587 Patient of 70 years ...

etc.

<?php
// Array obtained from file   
$array = file($file, true);

// Decompile array with foreach loop
foreach($array as $value)
{
   
//    Take away numbers 100-999
    //    Starting from biggest
    //
    //    %            Delimiter
    //    ^            Make match from beginning of line
    //    [0-9]        Range of numbers
    //    {3}        Multiplication of digit range (For tree digit numbers)
    //
   
if(preg_match('%^[0-9]{3}%', $value))
    {
       
// Re-assing to value its modified copy
       
$value = preg_replace('%^[0-9]{3}%', '-HERE WAS XXX NUMBER-', $value, 1);
    }
               
   
// Take away numbers 10-99
   
elseif(preg_match('%^[0-9]{2}%', $value)) {
       
$value = preg_replace('%^[0-9]{2}%', '-HERE WAS XX NUMBER-', $value, 1);
    }
               
   
// Take away numbers 0-9
   
elseif(preg_match('%^[0-9]%', $value)) {
       
$value = preg_replace('%^[0-9]%', '-HERE WAS X NUMBER-', $value, 1);
    }
               
   
// Build array back
   
$arr[] = array($value);
   
    }
}
?>
up
0
7r6ivyeo at mail dot com
15 years ago
String to filename:

<?php
function string_to_filename($word) {
   
$tmp = preg_replace('/^\W+|\W+$/', '', $word); // remove all non-alphanumeric chars at begin & end of string
   
$tmp = preg_replace('/\s+/', '_', $tmp); // compress internal whitespace and replace with _
   
return strtolower(preg_replace('/\W-/', '', $tmp)); // remove all non-alphanumeric chars except _ and -
}
?>

Returns a usable & readable filename.
up
0
ismith at nojunk dot motorola dot com
16 years ago
Be aware that when using the "/u" modifier, if your input text contains any bad UTF-8 code sequences, then preg_replace will return an empty string, regardless of whether there were any matches.

This is due to the PCRE library returning an error code if the string contains bad UTF-8.
up
0
steven -a-t- acko dot net
20 years ago
People using the /e modifier with preg_replace should be aware of the following weird behaviour. It is not a bug per se, but can cause bugs if you don't know it's there.

The example in the docs for /e suffers from this mistake in fact.

With /e, the replacement string is a PHP expression. So when you use a backreference in the replacement expression, you need to put the backreference inside quotes, or otherwise it would be interpreted as PHP code. Like the example from the manual for preg_replace:

preg_replace("/(<\/?)(\w+)([^>]*>)/e",
             "'\\1'.strtoupper('\\2').'\\3'",
             $html_body);

To make this easier, the data in a backreference with /e is run through addslashes() before being inserted in your replacement expression. So if you have the string

He said: "You're here"

It would become:

He said: \"You\'re here\"

...and be inserted into the expression.
However, if you put this inside a set of single quotes, PHP will not strip away all the slashes correctly! Try this:

print ' He said: \"You\'re here\" ';
Output: He said: \"You're here\"

This is because the sequence \" inside single quotes is not recognized as anything special, and it is output literally.

Using double-quotes to surround the string/backreference will not help either, because inside double-quotes, the sequence \' is not recognized and also output literally. And in fact, if you have any dollar signs in your data, they would be interpreted as PHP variables. So double-quotes are not an option.

The 'solution' is to manually fix it in your expression. It is easiest to use a separate processing function, and do the replacing there (i.e. use "my_processing_function('\\1')" or something similar as replacement expression, and do the fixing in that function).

If you surrounded your backreference by single-quotes, the double-quotes are corrupt:
$text = str_replace('\"', '"', $text);

People using preg_replace with /e should at least be aware of this.

I'm not sure how it would be best fixed in preg_replace. Because double-quotes are a really bad idea anyway (due to the variable expansion), I would suggest that preg_replace's auto-escaping is modified to suit the placement of backreferences inside single-quotes (which seemed to be the intention from the start, but was incorrectly applied).
up
-1
jette at nerdgirl dot dk
15 years ago
I use this to prevent users from overdoing repeated text. The following function only allows 3 identical characters at a time and also takes care of repetitions with whitespace added.

This means that 'haaaaaaleluuuujaaaaa' becomes 'haaaleluuujaaa' and 'I am c o o o o o o l' becomes 'I am c o o o l'

<?php
//Example of user input
$str = "aaaaaaaaaaabbccccccccaaaaad d d d   d      d d ddde''''''''''''";

function
stripRepeat($str) {
 
//Do not allow repeated whitespace
 
$str = preg_replace("/(\s){2,}/",'$1',$str);
 
//Result: aaaaaaaaaaabbccccccccaaaaad d d d d d d ddde''''''''''''

  //Do not allow more than 3 identical characters separated by any whitespace
 
$str = preg_replace('{( ?.)\1{4,}}','$1$1$1',$str);
 
//Final result: aaabbcccaaad d d ddde'''

 
return $str;
}
?>

To prevent any repetitions of characters, you only need this:

<?php
$str
= preg_replace('{(.)\1+}','$1',$str);
//Result: abcad d d d d d d de'
?>
up
-1
alves dot david at outlook dot com
6 years ago
// Function to format Brazilian taxvat using preg_replace
// Função para formatar o CPF ou CPF utilizando preg_replace
if (!function_exists('cpf_cnpj')) {
    function cpf_cnpj($cpf_cnpj)
    {
        if (!in_array(strlen($cpf_cnpj), [11, 14])) {
            return $cpf_cnpj;
        }

        if (strlen($cpf_cnpj) == 11) {
            return preg_replace("/(\d{3})(\d{3})(\d{3})(\d{2})/", "$1.$2.$3-$4", $cpf_cnpj);
        } else {
            return preg_replace("/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/", "$1.$2.$3/$4-$5", $cpf_cnpj);
        }
    }
}

echo cpf_cnpj(12345678901), ' - ', cpf_cnpj(12345678000190);

// 123.456.789-01 - 12.345.678/0001-90
To Top