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.
preg_replace
(PHP 4, PHP 5)
preg_replace — Realizar una operación de búsqueda y reemplazo con expresiones regulares
Descripción
Busca en asunto por coincidencias con patron y las reemplaza con reemplazo .
Lista de parámetros
- patron
-
El patrón a buscar. Puede ser una cadena o una matriz con cadenas.
El modificador e hace que preg_replace() trate el parámetro reemplazo como código PHP después de que las sustituciones de referencias correspondientes son realizadas. Consejo: asegúrese de que reemplazo constituya una cadena de código PHP válido, de otra forma PHP se quejará sobre un error de análisis sintáctico en la línea que contiene la llamada a preg_replace().
- reemplazo
-
La cadena o una matriz con las cadenas de reemplazo. Si este parámetro es una cadena y el parámetro patron es una matriz, todos los patrones serán reemplazados por esa cadena. Si tanto patron como reemplazo son matrices, cada patron será reemplazado por su contraparte en reemplazo . Si hay menos claves en la matriz reemplazo que en la matriz patron , los patrones extra serán reemplazados con una cadena vacía.
reemplazo puede contener referencias de la forma \\n o (desde PHP 4.0.4) $n, siendo este último estilo el más recomendable. Cada referencia de este tipo será reemplazada con el texto capturado por el nésimo patrón entre paréntesis. n puede ser un valor de 0 a 99, y \\0 o $0 hacen referencia al texto coincidente con el patrón completo. Los paréntesis de apertura son contados de izquierda a derecha (comenzando en 1) para obtener el número del sub-patrón de captura.
Cuando se trabaja con un patrón de reemplazo en donde una referencia hacia atrás está inmediatamente seguida por otro número (es decir, se coloca un número literal inmediatamente después de un patrón coincidente), no es posible usar la familiar notación \\1 para la referencia hacia atrás. \\11, por ejemplo, confundiría a preg_replace() ya que no es claro si se desea la referencia hacia atrás \\1 seguida de un 1 literal, o la referencia hacia atrás \\11 seguida por nada. En este caso la solución es usar \${1}1. Esto crea una referencia hacia atrás separada $1, dejando el 1 como una secuencia literal.
Cuando se usa el modificador e, esta función escapa algunos caracteres (a saber ', ", \ y NULL) en las cadenas que reemplazan las referencias hacia atrás. Esto es hecho para asegurarse de que no surjan errores de sintaxis por el uso de referencias hacia atrás con comillas simples o dobles (p.ej. 'strlen(\'$1\')+strlen("$2")'). Asegúrese de conocer la sintaxis de cadenas de PHP para saber exactamente cómo lucirá la cadena interpretada.
- asunto
-
La cadena o una matriz con cadenas para buscar y reemplazar.
Si asunto es una matriz, entonces la operación de búsqueda y reemplazo se realiza sobre cada entrada de asunto , y el valor de retorno es una matriz también.
- limite
-
La cantidad máxima posible de reemplazos para cada patrón en cada cadena asunto . Su valor predeterminado es -1 (sin límite).
- conteo
-
Si se especifica, esta variables será llenada con el número de reemplazos realizados.
Valores retornados
preg_replace() devuelve una matriz si el parámetro asunto es una matriz, o una cadena de lo contrario.
Si se encuentran coincidencias, el nuevo asunto será devuelto, de otra forma asunto será devuelto intacto.
Registro de cambios
| Versión | Descripción |
|---|---|
| 5.1.0 | Se agregó el parámetro conteo |
| 4.0.4 | Se agregó la forma '$n' para el parámetro reemplazo |
| 4.0.2 | Se agregó el parámetro limite |
Ejemplos
Example #1 Uso de referencias hacia atrás seguidas de literales numéricos
<?php
$cadena = 'April 15, 2003';
$patron = '/(\w+) (\d+), (\d+)/i';
$reemplazo = '${1}1,$3';
echo preg_replace($patron, $reemplazo, $cadena);
?>
El resultado del ejemplo seria:
April1,2003
Example #2 Uso de matrices indexadas con preg_replace()
<?php
$cadena = 'The quick brown fox jumped over the lazy dog.';
$patrones[0] = '/quick/';
$patrones[1] = '/brown/';
$patrones[2] = '/fox/';
$reemplazos[2] = 'bear';
$reemplazos[1] = 'black';
$reemplazos[0] = 'slow';
echo preg_replace($patrones, $reemplazos, $cadena);
?>
El resultado del ejemplo seria:
The bear black slow jumped over the lazy dog.
Ordenando por clave los patrones y reemplazos, podemos obtener lo que queríamos.
<?php
ksort($patrones);
ksort($reemplazos);
echo preg_replace($patrones, $reemplazos, $cadena);
?>
El resultado del ejemplo seria:
The slow black bear jumped over the lazy dog.
Example #3 Reemplazo de varios valores
<?php
$patrones = array ('/(19|20)(\d{2})-(\d{1,2})-(\d{1,2})/',
'/^\s*{(\w+)}\s*=/');
$reemplazar = array ('\3/\4/\1\2', '$\1 =');
echo preg_replace($patrones, $reemplazar, '{fechaInicio} = 1999-5-27');
?>
El resultado del ejemplo seria:
$fechaInicio = 5/27/1999
Example #4 Uso del modificador 'e'
<?php
preg_replace("/(<\/?)(\w+)([^>]*>)/e",
"'\\1'.strtoupper('\\2').'\\3'",
$cuerpo_html);
?>
Esto pasaría a mayúsculas todas las etiquetas HTML en el texto de entrada.
Example #5 Eliminar espacios en blanco
Este ejemplo remueve espacios de más de una cadena.
<?php
$cadena = 'foo o';
$cadena = preg_replace('/\s\s+/', ' ', $cadena);
// Ahora sera 'foo o'
echo $cadena;
?>
Example #6 Uso del parámetro conteo
<?php
$conteo = 0;
echo preg_replace(array('/\d/', '/\s/'), '*', 'xp 4 to', -1 , $conteo);
echo $conteo; //3
?>
El resultado del ejemplo seria:
xp***to 3
Notes
Note: Cuando se usan matrices con patron y reemplazo , las claves son procesadas en el orden en que aparecen en la matriz. Esto no es necesariamente lo mismo que el orden de índices numéricos. Si usan índices para identificar cuál patron debería ser reemplazado por cuál reemplazo , debería usar ksort() sobre cada matriz antes de llamar preg_replace().
preg_replace
28-Aug-2008 11:41
23-Aug-2008 05:42
preg_replace is greedy by default, and the behaviour of ? on the pattern is to make it non-greedy contrary to what i read on PCRE docs.
<?php
$str ="asdfd adsfd aaaadasd";
$str = preg_replace("/(a)(.*)(d)/","a($2)d",$str);
// a(sdfd adsfd aaaadas)d
$str = preg_replace("/(a)(.*)?(d)/U","a($2)d",$str);
// a(s)dfd a()dsfd a(aaa)da(s)d
?>
which is what i wanted.
08-Aug-2008 06:02
for simple templating use:
$TEMPLATE= "
<span style='float:right;text-align:right'>
{NAME}
{WEBSITE}
{PROFILE}
{OPTIONS}
</span>";
$NAME = $variable_name;
$WEBSITE = 'www';
$PROFILE = $user_id;
$OPTIONS = $user_opt;
$text = preg_replace('/\{(\w+)\}/e', '$$1', $TEMPLATE);
print $text;
31-Jul-2008 10:08
<?PHP
function strip_tags_attributes($sSource, $aAllowedTags = FALSE, $aDisabledAttributes = FALSE, $aAllowedProperties = 'font|font-size|font-weight|color' . '|text-align|text-decoration|margin|margin-left' . '|margin-top|margin-bottom|margin-right|padding' . '|padding-top|padding-left|padding-right|padding-bottom' . '|width|height'){
if( !is_array( $aDisabledAttributes ) ){
$aDisabledAttributes = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavaible', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragdrop', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterupdate', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmoveout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
}
$sSource = stripcslashes( $sSource );
$sSource = strip_tags( $sSource, $aAllowedTags );
if( empty($aDisabledAttributes) ){
return $sSource;
}
$aDisabledAttributes = @ implode('|', $aDisabledAttributes);
$sSource = preg_replace('/<(.*?)>/ie', "'<' . preg_replace(array('/javascript:[^\"\']*/i', '/(" . $aDisabledAttributes . ")[ \\t\\n]*=[ \\t\\n]*[\"\'][^\"\']*[\"\']/i', '/\s+/'), array('', '', ' '), stripslashes('\\1')) . '>'", $sSource );
$sSource = preg_replace('/\s(' . $aDisabledAttributes . ').*?([\s\>])/', '\\2', $sSource);
$regexp = '@([^;"]+)?(?<!'. $aAllowedProperties .'):(?!\/\/(.+?)\/)((.*?)[^;"]+)(;)?@is';
$sSource = preg_replace($regexp, '', $sSource);
$sSource = preg_replace('@[a-z]*=""@is', '', $sSource);
return $sSource;
}
?>
Online resource help skype name : globya
good luck !
30-Jul-2008 01:21
People using functions like scandir with user input and protecting against "../" by using preg_replace make sure you run ir recursivly untill preg_match no-long finds it, because if you don't the following can happen.
If a user gives the path:
"./....//....//....//....//....//....//....//"
then your script detects every "../" and removes them leaving:
"./../../../../../../../"
Which is proberly going back enough times to show root.
I just found this vunrability in an old script of mine, which was written several years ago.
Always do:
<?php
while( preg_match( [expression], $input ) )
{
$input = preg_replace( [expression], "", $input );
}
?>
30-Jul-2008 09:34
I just was trying to make a negated replace with a string NOT being in another string.
The code that is actually working:
<?php
$result = preg_replace('#{(?!disable1|disable2)[a-z0-9]+}#is', '$1', $foo);
?>
This code matches on all strings that do NOT start with "disable1" or "disable2" and contain of a-z0-9. It took me several hours to figuere out this very easy example!
Hope anyone could use it
25-Jul-2008 07:56
<?
//:::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
?>
16-Jul-2008 07:23
When you use the '$1', '$2', etc. replacement values, they can be either in double or single quotes. There is no need to worry about the dollar sign being interpreted as a variable or not:
<?php
print preg_replace("/I want (\S+) one/", "$1 is the one I want", "I want that one") . "\n";
print preg_replace("/I want (\S+) one/", '$1 is the one I want', "I want that one") . "\n";
?>
Both lines will print "that is the one I want".
11-Jul-2008 08:59
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.
07-Jul-2008 07:22
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.
07-Jul-2008 07:46
A bit easier to read and probably more efficient will be
<?php
function preg_escape($s = '')
{
return preg_replace('/[]\\\\^$.|?*+(){}[]/', '\\\\$0', $s);
}
?>
25-Jun-2008 06:15
Here's some handy-dandy code that will properly escape a string that includes regex special characters.
<?php
$x = "
/\\[|\\\\|\\^|\\$|\\.|\\||\\?
|\\*|\\+|\\(|\\)|\\{|\\}/
";
$escaped_string = preg_replace($x, "\\\\$0", $in_string);
?>
This is useful if you are generating dynamic regular expressions based on user input. With the above example, the $escaped_string variable is now ready to be used in another regular expression as the search variable.
21-Jun-2008 03:09
A simple BB like thing..
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;
}
<!-- -->
Let me know of any error(s) :)
16-Apr-2008 07:35
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.
24-Mar-2008 11:45
This is in response to iasmin at amazingdiscoveries dot org's URL text to link function. Hope this is helpful to someone.
I played with it a bit and came up with this version (there were one or two little errors in the regex I think, also -- it didn't allow various necessary characters).
I start with a URL in brackets (this works for my case):
[http://www.site.com/path/that/may/be_long.php?fun=1]
It returns a link of the URL after the "http://":
www.site.com/path/that/may/b...
-----------
// Cuts off long URLs at $url_length, and appends "..."
function reduceurl($url, $url_length) {
$reduced_url = substr($url, 0, $url_length);
if (strlen($url) > $url_length) $reduced_url .= '...';
return $reduced_url;
}
// Makes URLs with brackets into links
// The regex searches for "http://" or equivalent, then various character possibilities (I don't know if it might be possible to exploit this if more characters were allowed). The "e" after the regex allows the reduceurl() to be evaluated.
function url2link($linktext) {
$linktext = preg_replace("#\[(([a-zA-Z]+://)([a-zA-Z0-9?&%.;:/=+_-]*))\]#e", "'<a href=\"$1\" target=\"_blank\">' . reduceurl(\"$3\", 30) . '</a>'", $linktext);
return $linktext;
}
29-Feb-2008 05:02
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!
15-Jan-2008 06:53
Jacob Fogg's clean_filename function is good, but there is a typo. Replace "\\x00-\\x40" with "\\x00-\\x20" or you will exclude too many characters.
Also keep in mind when checking file names to look for the special directory names ".." and ".". A user could potentially use those to reach an unexpected directory.
14-Jan-2008 06:29
Here is my attempt at cleaning up a file name... it's similar to what someone else has done however a little cleaner with the addition of the | in the reserved characters... also I clean any characters from x00 to x40 (all non display characters and space) as well as everything greater than 7f and greater (removes the Del character and other non English characters), replacing them with an '_'.
function clean_filename($filename){//function to clean a filename string so it is a valid filename
$reserved = preg_quote('\/:*?"<>|', '/');//characters that are illegal on any of the 3 major OS's
//replaces all characters up through space and all past ~ along with the above reserved characters
return preg_replace("/([\\x00-\\x40\\x7f-\\xff{$reserved}])/e", "_", $filename);
}
11-Dec-2007 01:17
Actually I made a mistake in my previous post. In order to make the function more effective ... I broke it. The original which works (really) looks like this:
<?php
function repl_amp($text)
{
$text=preg_replace("/&(?!amp;)/i", "&", $text);
$text=preg_replace("/&#(\d+);/i", "&#$1;", $text); // For numeric entities
$text=preg_replace("/&(\w+);/i", "&$1;", $text); // For literal entities
return $text;
}
?>
The RegEx Tester says that the first expression is OK, but when testing with various entities, some of them came out broken. I'd tried to use only 2 preg_replace(); calls instead of three by using the alternative branch from the pattern syntax - which didn't came out well. Sorry for the previous error, and I still hope that someone can find a better alternative.
07-Dec-2007 03:28
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.
30-Nov-2007 05:26
This code is much easier than preg_replaces current implementation, I stole some of this from someone else here, but to make it more explicit:
$relation['/pattern/'] = "replacement";
$text_out = preg_replace(array_keys($relation), array_values($relation), $text_in);
Fast, efficient, no guess work..
23-Oct-2007 03:35
@giel dot berkers
Use the 'PCRE_DOTALL' ('s') option so that the '.' covers newline characters:
$code = preg_replace('/\/\*.*\*\//ms', '', $code);
18-Oct-2007 12:49
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.
<?
//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 :)
If anyone finds a better way, please let met know, I'm still learning ;)
28-Sep-2007 12:52
at below post:
<?php
$template = "Price: #price#";
$price = '$5';
print "Price: $price\n";
$res = preg_replace("/#price#/", $price, $template);
print "From template: -> $res\n";
?>
20-Sep-2007 10:52
@ Santosh Patnaik
The perl regular expression engine will handle this expression better and much faster by using the word boundry escape code \b. Though it may not be obvious except to long time perl geeks such as I :)
so:
// Expect and get 'pa pa pa pa'
echo preg_replace('`\bma\b`', 'pa', 'ma ma ma ma');
Jeff
14-Sep-2007 03:11
Once a match is identified, the regular expression engine appears to set aside the matching segment of the target string. A second segment that you expect to match may therefore end up not getting matched:
// Expect 'pa pa pa pa' but get 'pa ma pa ma'
echo preg_replace('`(^|\s)ma(\s|$)`', '$1pa$2', 'ma ma ma ma');
Here the issue can be solved by using a 'lookahead':
// Expect and get 'pa pa pa pa'
echo preg_replace('`(^|\s)ma(?=\s|$)`', '$1pa', 'ma ma ma ma');
12-Sep-2007 11:37
I thought that someone could use this hyperlink function.
preg_replace is about 6 times faster than ereg_replace. I took the original example from the ereg_replace function page and modified so that it works perfect. I gave a comment of what it matches.
One thing is that I added a space at the beginning so that only links that don't have <a href="" around them or anything else touching will be replaced.
<i>NOTE! I had to break the long lines otherwise I couldn't have posted this. So take the new line out and it will work</i>
<?php
function hyperlink(&$text)
{
// match protocol://address/path/file.extension?some=variable&another=asf%
$text = preg_replace("/\s(([a-zA-Z]+:\/\/)([a-z][a-z0-9_\..-]*
[a-z]{2,6})([a-zA-Z0-9\/*-?&%]*))\s/i", " <a href=\"$1\">$3</a> ", $text);
// match www.something.domain/path/file.extension?some=variable&another=asf%
$text = preg_replace("/\s(www\.([a-z][a-z0-9_\..-]*
[a-z]{2,6})([a-zA-Z0-9\/*-?&%]*))\s/i", " <a href=\"http://$1\">$2</a> ", $text);
return $text;
}
?>
Play around with it and see how it works.
Courtesy of AmazingDiscoveries.org
God bless, Iasmin Balaj
24-Aug-2007 07:10
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:
$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:
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
21-Aug-2007 05:48
Also worth noting is that you can use array_keys()/array_values() with preg_replace like:
$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);
25-Jul-2007 05:15
I got problem echoing text that contains double-quotes into a text field. As it confuses value option. I use this function below to match and replace each pair of them by smart quotes. The last one will be replaced by a hyphen(-).
It works for me.
function smart_quotes($text) {
$pattern = '/"((.)*?)"/i';
$text = preg_replace($pattern,"“\\1”",stripslashes($text));
$text = str_replace("\"","-",$text);
$text = addslashes($text);
return $text;
}
17-Jul-2007 08:37
Based on previous comment, i suggest
( this function already exist in php 6 )
function unicode_decode($str){
return preg_replace(
'#\\\u([0-9a-f]{4})#e',
"unicode_value('\\1')",
$str);
}
function unicode_value($code) {
$value=hexdec($code);
if($value<0x0080)
return chr($value);
elseif($value<0x0800)
return chr((($value&0x07c0)>>6)|0xc0)
.chr(($value&0x3f)|0x80);
else
return chr((($value&0xf000)>>12)|0xe0)
.chr((($value&0x0fc0)>>6)|0x80)
.chr(($value&0x3f)|0x80);
}
21-Mar-2007 02:47
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.
07-Mar-2007 01:30
I could not find a function to unescape javascript unicode escapes anywhere (e.g., "\u003c"=>"<").
<?php
function js_uni_decode($s) {
return preg_replace('/\\\u([0-9a-f]{4})/ie', "chr(hexdec('\\1'))", $s);
}
echo js_uni_decode("\u003c");
?>
07-Feb-2007 04:09
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.
07-Sep-2006 06:21
Wasted several hours because of this:
$str='It'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 �
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 print(011);
Solution:
preg_replace('~�*(\d+);~e', 'code2utf($1)', $str);
21-Apr-2006 09:15
For those of you that have ever had the problem where clients paste text from msword into a CMS, where word has placed all those fancy quotes throughout the text, breaking the XHTML validator... I have created a nice regular expression, that replaces ALL high UTF-8 characters with HTML entities, such as ’.
Note that most user examples on php.net I have read, only replace selected characters, such as single and double quotes. This replaces all high characters, including greek characters, arabian characters, smilies, whatever.
It took me ages to get it just downto two regular expressions, but it handles all high level characters properly.
$text = preg_replace('/([\xc0-\xdf].)/se', "'&#' . ((ord(substr('$1', 0, 1)) - 192) * 64 + (ord(substr('$1', 1, 1)) - 128)) . ';'", $text);
$text = preg_replace('/([\xe0-\xef]..)/se', "'&#' . ((ord(substr('$1', 0, 1)) - 224) * 4096 + (ord(substr('$1', 1, 1)) - 128) * 64 + (ord(substr('$1', 2, 1)) - 128)) . ';'", $text);
18-Oct-2004 05:39
It is useful to note that the 'limit' parameter, when used with 'pattern' and 'replace' which are arrays, applies to each individual pattern in the patterns array, and not the entire array.
<?php
$pattern = array('/one/', '/two/');
$replace = array('uno', 'dos');
$subject = "test one, one two, one two three";
echo preg_replace($pattern, $replace, $subject, 1);
?>
If limit were applied to the whole array (which it isn't), it would return:
test uno, one two, one two three
However, in reality this will actually return:
test uno, one dos, one two three
08-Feb-2004 02:45
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).
23-Oct-2003 11:38
I got sick of trying to replace just a word, so I decided I would write my own string replacement code. When that code because far to big and a little faulty I decided to use a simple preg_replace:
<?php
/**
* Written by Rowan Lewis of PixelCarnage.com
* $search(string), the string to be searched for
* $replace(string), the string to replace $search
* $subject(string), the string to be searched in
*/
function word_replace($search, $replace, $subject) {
return preg_replace('/[a-zA-Z]+/e', '\'\0\' == \'' . $search . '\' ? \'' . $replace . '\': \'\0\';', $subject);
}
?>
I hope that this code helpes someone!
