preg_replace -- 执行正则表达式的搜索和替换

preg_replace

(PHP 3>= 3.0.9, PHP 4 , PHP 5)

preg_replace -- 执行正则表达式的搜索和替换

说明

mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit] )

subject 中搜索 pattern 模式的匹配项并替换为 replacement。如果指定了 limit,则仅替换 limit 个匹配,如果省略 limit 或者其值为 -1,则所有的匹配项都会被替换。

replacement 可以包含 //n 形式或(自 PHP 4.0.4 起)$n 形式的逆向引用,首选使用后者。每个此种引用将被替换为与第 n 个被捕获的括号内的子模式所匹配的文本。n 可以从 0 到 99,其中 //0$0 指的是被整个模式所匹配的文本。对左圆括号从左到右计数(从 1 开始)以取得子模式的数目。

对替换模式在一个逆向引用后面紧接着一个数字时(即:紧接在一个匹配的模式后面的数字),不能使用熟悉的 //1 符号来表示逆向引用。举例说 //11,将会使 preg_replace() 搞不清楚是想要一个 //1 的逆向引用后面跟着一个数字 1 还是一个 //11 的逆向引用。本例中的解决方法是使用 /${1}1。这会形成一个隔离的 $1 逆向引用,而使另一个 1 只是单纯的文字。

例子 1. 逆向引用后面紧接着数字的用法

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

/* Output
   ======

April1,2003

 */
?>

如果搜索到匹配项,则会返回被替换后的 subject,否则返回原来不变的 subject

preg_replace() 的每个参数(除了 limit)都可以是一个数组。如果 patternreplacement 都是数组,将以其键名在数组中出现的顺序来进行处理。这不一定和索引的数字顺序相同。如果使用索引来标识哪个 pattern 将被哪个 replacement 来替换,应该在调用 preg_replace() 之前用 ksort() 对数组进行排序。

例子 2. 在 preg_replace() 中使用索引数组

<?php
$string
= "The quick brown fox jumped over the lazy dog.";

$patterns[0] = "/quick/";
$patterns[1] = "/brown/";
$patterns[2] = "/fox/";

$replacements[2] = "bear";
$replacements[1] = "black";
$replacements[0] = "slow";

print
preg_replace($patterns, $replacements, $string);

/* Output
   ======

The bear black slow jumped over the lazy dog.

*/

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

ksort($patterns);
ksort($replacements);

print
preg_replace($patterns, $replacements, $string);

/* Output
   ======

The slow black bear jumped over the lazy dog.

*/

?>

如果 subject 是个数组,则会对 subject 中的每个项目执行搜索和替换,并返回一个数组。

如果 patternreplacement 都是数组,则 preg_replace() 会依次从中分别取出值来对 subject 进行搜索和替换。如果 replacement 中的值比 pattern 中的少,则用空字符串作为余下的替换值。如果 pattern 是数组而 replacement 是字符串,则对 pattern 中的每个值都用此字符串作为替换值。反过来则没有意义了。

/e 修正符使 preg_replace()replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。

例子 3. 替换数个值

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

本例将输出:

$startDate = 5/27/1999

例子 4. 使用 /e 修正符

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

这将使输入字符串中的所有 HTML 标记变成大写。

例子 5. 将 HTML 转换成文本

<?php
// $document 应包含一个 HTML 文档。
// 本例将去掉 HTML 标记,javascript 代码
// 和空白字符。还会将一些通用的
// HTML 实体转换成相应的文本。

$search = array ("'<script[^>]*?>.*?</script>'si"// 去掉 javascript
                
"'<[///!]*?[^<>]*?>'si",          // 去掉 HTML 标记
                
"'([/r/n])[/s]+'",                // 去掉空白字符
                
"'&(quot|#34);'i",                // 替换 HTML 实体
                
"'&(amp|#38);'i",
                
"'&(lt|#60);'i",
                
"'&(gt|#62);'i",
                
"'&(nbsp|#160);'i",
                
"'&(iexcl|#161);'i",
                
"'&(cent|#162);'i",
                
"'&(pound|#163);'i",
                
"'&(copy|#169);'i",
                
"'&#(/d+);'e");                    // 作为 PHP 代码运行

$replace = array ("",
                
"",
                
"//1",
                
"/"",
                
"&",
                
"<",
                
">",
                
" ",
                
chr(161),
                
chr(162),
                
chr(163),
                
chr(169),
                
"chr(//1)");

$text = preg_replace ($search, $replace, $document);
?>

注: limit 参数是 PHP 4.0.1pl2 之后加入的。

参见 preg_match()preg_match_all()preg_split()



add a note add a note User Contributed Notes
preg_replace
doron88 at gmail dot com
23-Mar-2005 07:00
Hello all php experts :),

I have a little question:
I have a string, want to highlight all php codes from this string, how shall I do it?

that's my code:
<?php

function phpcode($string)
//finds and highlight php codes from the string
{
return
preg_replace('!/[PHP/]/s*(.*?)/s*/[//PHP/]!i',
                    
'<br />PHP Code:<p dir="ltr">'.
                    
highlight_string('$1',TRUE).
                    
'</p>',
                    
$string);

?>
naaina at gmail dot com
16-Mar-2005 02:25
If you want to remove a parameter from an URL, use this function:

<?php
 
function url_remove_parameter($pURL, $pParameter){
  return
preg_replace("/(&|/?)" . $pParameter . "=(.+?)(&|$)/", "//1", $pURL);
 }
?>
jack at jcxp dot net
13-Mar-2005 06:08
My Perfect Highlighting Function :)

<?php
function highlight($text, $search) {
  
$text = preg_replace( "/(^|/s|,!|;)(".preg_quote($search, "/").")(/s|,|!|&|$)/i", "//1<span class='hlstyle'>//2</span>//3", $text );
   return
$text;
}
?>
Jay Blackwood
09-Mar-2005 09:58
Don't forget that the regular expression, 'pattern', MUST include the slashes on either end!  If you forget you get a very unhelpful message, "Warning: Delimiter must not be alphanumeric ".

It is really easy to forget these delimeters as they are in many ways part of the syntax of a given PERL command, not the regular expression.
07-Mar-2005 07:58
Here you have very usefull script to convert links to robots friendly, and read parameters in your page. I tested this in the site http://www.proanglo.com
You can use links in you page in such form:

http://www.example.com/file.php/s1=1/s2=2/s3=3
OR
http://www.example.com/file.php/s1=1,s2=2,s3=3

Your script:

<?php

   $adres
= $_SERVER["PATH_INFO"];
  
$res = preg_replace('@(/w+)=(/w+)@e', '$//1="//2";', $adres);
  
var_dump($s1, $s2, $s3);

?>
Anca Zaharia
04-Mar-2005 05:31
Simple function to strip multiple white spaces in a string:

$sample = preg_replace('//s/s+/', ' ', $sample);
php at ihid dot co dot uk
26-Feb-2005 10:42
In the function :
$xml = preg_replace("asd", "/$1".$text."/$2", $xml);

if text starts or finished with a number you will have unexpected behaviour.

If $text = "3asd" for instance, the function will be
$xml = preg_replace("asd", "/$13asd/$2", $xml);

Rather than trying to parse $1 like we want, it will try to use $13, giving a very different result.

Confused me for ages.
jhm at cotren dot net
18-Feb-2005 05:04
It took me a while to figure this one out, but here is a nice way to use preg_replace to convert a hex encoded string back to clear text

<?php
   $text
= "PHP rocks!";
  
$encoded = preg_replace(
          
"'(.)'e"
        
,"dechex(ord('//1'))"
        
,$text
  
);
   print
"ENCODED: $encoded/n";
?>
ENCODED: 50485020726f636b7321
<?php
  
print "DECODED: ".preg_replace(
      
"'([/S,/d]{2})'e"
    
,"chr(hexdec('//1'))"
    
,$encoded)."/n";
?>
DECODED: PHP rocks!
spam at barad-dur dot nl
17-Feb-2005 04:21
When you want to add searh highlights to your website you might find this useful.

<?php
function highlight($buff,$query) {
    
$query = explode($query,"+");
    
$class = 0;
     foreach(
$query as $word) {
          
$buff = highlight_word($buff,$word,$class);
          
$class++;
     }

     return
$buff;
}

function
highlight_word($buff,$query,$class) {
    
$pattern = "/>(.*?)</";
    
$pattern_sub = "/($query)/i";
    
$ret = preg_replace_callback($pattern,
        
create_function(
              
'$matches',
              
'return preg_replace("'.$pattern_sub.'","<span class=/"qr-'.$class.'/">$0</span>",$matches[0]);'
          
),
          
$buff;
     return
$ret;
}
?>

Where $buff is the content of your site and $query is the query via $_REQUEST (+ is an url-encoded space)
gbaatard at iinet dot net dot au
15-Feb-2005 12:56
on the topic of implementing forum code ([b][/b] to <b></b> etc), i found this worked well...

<?php
$body
= preg_replace('//[([biu])/]/i', '<//1>', $body);
$body = preg_replace('//[//([biu])/]/i', '<///1>', $body);
?>

First line replaces [b] [B] [i] [I] [u] [U] with the appropriate html tags(<b>, <i>, <u>)

Second one does the same for closing tags...

For urls, I use...

<?php
$body
= preg_replace('//s(/w+:)(/S+)/', ' <a href="//1//2" target="_blank">//1//2</a>', $body);
?>

and for urls starting with www., i use...

<?php
$body
= preg_replace('//s(www/.)(/S+)/', ' <a href="http:1//2" target="_blank">//1//2</a>', $body);
?>

Pop all these lines into a function that receives and returns the text you want 'forum coded' and away you go:)
info at atjeff dot co dot nz
07-Feb-2005 07:47
ive never used regex expressions till now and had loads of difficulty trying to convert a [url]link here[/url] into an href for use with posting messages on a forum, heres what i manage to come up with:

$patterns = array(
           "//[link/](.*?)/[//link/]/",
           "//[url/](.*?)/[//url/]/",
           "//[img/](.*?)/[//img/]/",
           "//[b/](.*?)/[//b/]/",
           "//[u/](.*?)/[//u/]/",
           "//[i/](.*?)/[//i/]/"
       );
       $replacements = array(
           "<a href=/"//1/">//1</a>",
           "<a href=/"//1/">//1</a>",
           "<img src=/"//1/">",
           "<b>//1</b>",
           "<u>//1</u>",
           "<i>//1</i>"
          
       );
       $newText = preg_replace($patterns,$replacements, $text);

at first it would collect ALL the tags into one link/bold/whatever, until i added the "?" i still dont fully understand it... but it works :)
pingju at stud dot ntnu dot no
03-Feb-2005 07:56
In example 5 shown above, it is said: $document should contain an HTML document.

As I can see, to remove the Javascript segment from $document, it must be a string, or only Javascript segment within one line of $document can be removed, i.e there is not /n in between <script and </script>.
mzvarik at gmail dot com
01-Feb-2005 11:19
This erase white-spaces on the beginning and the end in each line of a string:

<?
$str
= '    1. blah 
   2. blah bla 
  3. fdf ads fdf    '
;

echo
preg_replace('~^(/s*)(.*?)(/s*)$~m', "//2", $str);
?>
shogal at mail dot ru
01-Feb-2005 03:49
Quik way to highlight whole word:
<?
preg_replace
(
"/(^|[^/w]){1}(".preg_quote($search,"/").")($|[^/w]){1}/i",
"//1<span class='highlight'>//2</span>//3", $string);
?>
In some locales may not work so better way is to change /w to class of literals.
tash at quakersnet dot com
30-Jan-2005 07:25
A better way for link & email conversaion, i think. :)

<?php
function change_string($str)
   {
    
$str = trim($str);
    
$str = htmlspecialchars($str);
    
$str = preg_replace('#(.*)/@(.*)/.(.*)#','<a href="mailto://1@//2.//3">Send email</a>',$str);
    
$str = preg_replace('=([^/s]*)(www.)([^/s]*)=','<a href="http:2//3" target=/'_new/'>//2//3</a>',$str);
     return
$str;
   }
?>
levi at kodern dot com
29-Jan-2005 05:58
It took me a couple hours to figure this one out as I'm a newbie at regular expressions, and no one had posted about it. This will remove the parentheses and all any characters inside of them. i.e. phone number with parentheses or Yahoo's news feed.

preg_replace(" (/(.*?/))", "", $string)
Text505 At positivesale_nospam_ dot com
28-Jan-2005 02:41
When converting HTML to text, like in the php Manual example, you will want to strip out style tags and contents between these tags, in addition to javascript.

"'<style[^>]*?>.*?</style>'si",  //Strip out style tags

Replace with: ""
jw-php at valleyfree dot com
25-Jan-2005 11:28
note the that if you want to replace all backslashes in a string with double backslashes (like addslashes() does but just for backslashes and not quotes, etc), you'll need the following:

$new = preg_replace('//','',$old);

note the pattern uses 4 backslashes and the replacement uses 8!  the reason for 4 slashses in the pattern part has already been explained on this page, but nobody has yet mentioned the need for the same logic in the replacement part in which backslashes are also doubly parsed, once by PHP and once by the PCRE extension.  so the eight slashes break down to four slashes sent to PCRE, then two slashes put in the final output.
Nick
20-Jan-2005 06:05
Here is a more secure version of the link conversion code which hopefully make cross site scripting attacks more difficult.

<?php
function convert_links($str) {
      
$replace = <<<EOPHP
'<a href="'.htmlentities('//1').htmlentities('//2').//remove line break
'">'.htmlentities('
//1').htmlentities('//2').'</a>'
EOPHP;
  
$str = preg_replace('#(http://)([^/s]*)#e', $replace, $str);
   return
$str;
}
?>
jason at thinkingman dot org
16-Jan-2005 02:42
A follow-up to my previous posting on removing whitespace using preg_replace().

If you're just interested in removing SPACE characters only, keeping all /n or /r/n -- then try the following:

<?

     $str
= preg_replace("/([ ]+)?(/<.+/>)([ ]+)?/", "$2", ob_get_contents());

?>

Your HTML will format as if a TRIM() method was called on each line.

     <html>
     <head>
           <title>My Fantastic Website! </title>
     </head>
     <body>
           <?=$str?>     
     </body>
     </html>

will output as:

<html>
<head>
<title>My Fantastic Website! </title>
</head>
<body>
This is some text   
</body>
</html>

Jason
jason at thinkingman dot org (jason)
16-Jan-2005 12:25
Strip all whitespace around <TAGS>. 

This is useful for those who want to reduce the size of their web pages by eliminating all unnecessary whitespace (/r/n/t, etc...).  This code only removes the whitespace directly around a <TAG>, not the whitespace within a tag or within the string output of a tag.

For example:
<?
     ob_start
();
    
$str = " This is some text ";
?>

     <html>
     <head>
           <title>My Fantastic Website! </title>
     </head>
     <body>
           <?=$str?>     
     </body>
     </html>

<?
     $output
= preg_replace("/(/s+)?(/<.+/>)(/s+)?/", "$2"ob_get_contents());
    
ob_end_clean();
     echo
$output;
?>

The output will be (instead of formatted HTML, one nice long line of HTML, minus all unnecessary whitespace characters):

<html><head><title>My Fantastic Website!</title></head><body>This is some text</body></html>

Although a little-bit of overhead (and I do mean *little* to non-existent) is incurred, the BYTE savings can be extremely valuable; unnecessary code isn't transmitted over the line, your code becomes tight and clean (albeit, not desirably readable to anyone viewing your source), and pages download quicker, so on...

Use wisely.

Jason
Yunbin Bai
26-Nov-2004 07:56
If you want to use /e in the Reg expression, I think using escaped double quote is better than just single quote in the replacement parameter.
I meet this problem when I try to replace a string that contains double quote in it, it cost me some time to solve this. So I simplified my code and present here:

consider capitalize SSI directives in the input text:

$html_body = "<!--#include virtual=/"header.htm/" -->";
   //That is, source text: <!--#include virtual="header.htm" -->
$html_body = preg_replace('/(<!--#)(.*)(-->)/e', "'//1'.strtoupper('//2').'//3'", $html_body);

echo $html_body;
//output text: <!--#INCLUDE VIRTUAL=/"HEADER.HTM/" -->
//Result is not what you want: there is additional backslash generated that is useless.

My Solution to this:
use /" instead of ', that make it a little mess, but garanteed working.

$html_body = preg_replace('/(<!--#)(.*)(-->)/e', "/"//1/".strtoupper(/"//2/")./"//3/"", $html_body);
echo $html_body;

//result is correct now: <!--#INCLUDE VIRTUAL="HEADER.HTM" -->
adam at releod dot com
26-Nov-2004 06:50
In addition to pauls note. If you have a string as follows

"today I went to http://www.google.com it was great"

anything after the url is automatically parsed into the clickable link.

Quick fix as follows

<?
$text
= "Hello World. Today I visited http://www.google.com/ for the first time";

$text = preg_replace("/(http:(.*)//)[/S]*/", "<a href=//1>//1</a> ", $text);

echo
$text;
?>

Simply add // After the (.*)
manithu at fahr-zur-hoelle dot org
22-Nov-2004 08:26
This function is better than paul's, it 'stops' linking after a white-space. It also converts uris without http://(optional).

<?

function convert_links($str, $www = false) {
  
#this converts http://*  the link ends at the next space or(if there is no space) at the end of the string.
  
$str = preg_replace('#(http://)([^/s]*)#', '<a href="//1//2">//1//2</a>', $str);
  
#optional, replaces www.*
  
if($www) {
      
$str = preg_replace('=(www.)([^/s]*)=', '<a href="http:1//2">//1//2</a>', $str);
   }
   return
$str;
}

?>
zobier(at)hotmail(dot)com
01-Nov-2004 05:42
If you want to avoid filename conflicts, for example when handling uploaded files, this regex will append a digit before the extension or increment an existing one.
e.g.
my_file.ext >> my_file_1.ext
my_file1.ext >> my_file_2.ext
<?php
  
while ( file_exists ( "$uploaddir/$file_name" )) {
      
$file_name = preg_replace ( "/^(.+?)(_?)(/d*)(/.[^.]+)?$/e", "'/$1_'.(/$3+1).'/$4'", $file_name );
   }
?>
ignacio paz posse
21-Oct-2004 04:22
I needed to treat exclusively long urls and not shorter ones for which my client prefered to have their complete addresses displayed. Here's the function I end up with:

<?php
function auto_url($txt){

 
# (1) catch those with url larger than 71 characters
 
$pat = '/(http|ftp)+(?:s)?:(//)'
      
.'((//w|//.)+)(///)?(//S){71,}/i';
 
$txt = preg_replace($pat, "<a href=/"//0/" target=/"_blank/">$1$2$3/...</a>",
$txt);

 
# (2) replace the other short urls provided that they are not contained inside an html tag already.
 
$pat = '/(?<!href=/")(http|ftp)+(s)?:' .
     .
'(//)((//w|//.)+) (///)?(//S)/i';
 
$txt = preg_replace($pat,"<a href=/"$0/" target=/"_blank/">$0</a> ",
 
$txt);

  return
$txt;
}
?>
Note the negative look behind expression added in the second instance for exempting those that are preceded with ' href=" ' (meaning that they were already put inside appropiate html tags by the previous expression)

(get rid of the space between question mark and the last parenthesis group in both regex, I need to put it like that to be able to post this comment)
gabe at mudbuginfo dot com
18-Oct-2004 04: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
FP <firman at pribadi dot or dot id>
13-Oct-2004 03:58
just my 2cent tips for auto-linking url in text
- without "href=" defined!, if you need, modify it.
- it should work for any type url , modify it for specific protocol.
- just remove " //WRAPPED// ", so its became one line

more 2cent tips at http://sysadmin.eu.org/?blog_cat=code

<?php

$result
= preg_replace("/((http|ftp)+(s)?:()([/w]+(.[/w]+)) //WRAPPED// ([/w/-/.,@?^=%&:;//~/+#]*[/w/-/@?^=%&:;//~/+#])?)/i", "<a href=/"//0/">//0</a>", $text);

?>
Marko Zarkovic, Ottawa
01-Oct-2004 12:05
I spent a few hours trying to determine why I couldn't find a substring to replace in an HTML fragment.

$searchstr = "//"" . $linehash['item'] . "/"/";
$replacestr = "/"" . $linehash['item'] . "/" SELECTED";
$regexval = preg_replace($searchstr, $replacestr, $htmlfragment);

$linehash['item'] was a value read from a file.

I realized that I had to TRIM() invisibles from $linehash['item']. See the TRIM function for more information.
aidan at php dot net
22-Aug-2004 10:01
Here is a simple function for highlighting a needle in text. It is careful to not replace text in HTML tags (unless specified).

http://aidan.dotgeek.org/lib/?file=function.str_highlight.php

Example: The google method of highlighting

<?php
$text
= "Here is some text with a search term";
$needle = "search term";
echo
str_highlight($text, $needle);
?>

Output:
Here is some text with a <strong>search term</strong>
mike at iaym dot com
17-Apr-2004 01:22
This took a few hours of my life.  If you want to replace a string in a chunk of text WITHOUT replacing it in the html tags use the following: (i used this for a search engine to search a news database which includes html)

<?php
preg_replace
("'(?!<.*?)$string(?![^<>]*?>)'si", "REPLACED", $chunk);
?>
thesaur at php dot net
29-Mar-2004 08:30
Massimo 20-Feb-2004 01:46 wrote:

<?php
// ... snip ...
$msg = preg_replace("//[(/w+)/]/e", "/$//1", $str);
?>

"The above script will produce the desired output replacing variables inside brackets with values in the php script."

Doing this is not a very good idea, especially if you don't have full control of the text input. The problem with it is that you're likely to have variables you don't want made public (e.g., $password). Simply inserting a variable name in brackets will display it to the world. This is a major security problem, but won't matter if you're creating a small script for your own personal use, that will not be accessed by anyone else. Use at your own risk.
silasjpalmer at optusnet dot com dot au
19-Mar-2004 09:00
Using preg_rep to return extracts without breaking the middle of words
(useful for search results)

<?php
$string
= "Don't split words";
echo
substr($string, 0, 10); // Returns "Don't spli"

$pattern = "/(^.{0,10})(/W+.*$)/";
$replacement = "/${1}";
echo
preg_replace($pattern, $replacement, $string); // Returns "Don't"
?>
php at equaliser dot net
12-Mar-2004 09:07
If you're setting your replacement values elsewhere and your replacement value can contain a dollar sign followed by an integer eg:

$replacement = 'Dad's $7 shoes'

You'll find that preg_replace() treats this (quite rightly) as callback syntax.

So, you might want to do this:

$replacement = preg_replace("!" . '/x24' . "!" , '///$' , $replacement);

To your replacement string first; Putting in an escaped backslash '//' followed by an escaped dollar sign '/$' where every instance appears.
j-AT-jcornelius-DOT-com
24-Feb-2004 04:02
I noticed that a lot of talk here is about parsing URLs. Try the
parse_url() function in PHP to make things easier.

http://www.php.net/manual/en/function.parse-url.php

- J.
Massimo
20-Feb-2004 10:46
I've made a little modification to the code written by daniil for replacing variables inside brackets with values because if there is there isn't spaces between tags that we want to replace it doesn't work. Using '/w' instead of /S solve this problem.
Example:
<?php
// This is taken from somewhere and written in PHP
$str = 'Hello, [name]
This is my phone number [phone]-[number]'
;

// Those are the variables to be replaced with inside []
$name = 'Mike';
$phone = '+39';
$number = '555...';

$msg = preg_replace("//[(/w+)/]/e", "/$//1", $str);
print
$msg;
?>

The above script will produce the desired output replacing variables inside brackets with values in the php script.
steven -a-t- acko dot net
08-Feb-2004 12: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).
daniil at nycfoto dot com
24-Dec-2003 12:57
I've had this problem where I had to take a message from the database and replace special strings into some useful data. Since others might want to do the same, here is an example:

<?php
// This is taken from somewhere and written in PHP
$str = 'Hello, [name]

thank you for bla & bla,

Sincerely,

[team_name]'
;

// Those are the variables to be replaced with inside []
$name = 'Mike';
$team_name = 'Company XYZ';

$msg = preg_replace("//[(/S+)/]/e", "/$//1", $str);
print
$msg;
?>

The above script will produce the desired output replacing variables inside brackets with values in the php script.
martin at vertikal dot dk
22-Dec-2003 08:11
Opposite most expamles mentioned here, I needed to replace "proper" HTML-formatted URL's with stripped down http-URL's to be used in a non-HTML newsletter. This would enable non-HTML newsletter subscribers to click directly on the URL.

This small function did it for me:
$txt = preg_replace("/<a href=/"(.*)/">(.*)<//a>/i", "//2 (//1)", $txt);

This will strip the tag <a href="xxx"> and its matching closing tag </a> but keep the text (here: xxx) between them. After this it will place the original URL in parenthesis. You can fiddle the sequence and formatting of the variables 1 (URL) and 2 (link text) as you please.

I can now pass the result of a text with HTML-formatted URL's from my CMS directly through this small funtion and into an email.

I haven't tested this thoroughly with all types of text, complex HTML or strange URL's, but it works well in my controlled environment.

Martin
kweejee at clan-zzq dot org
15-Dec-2003 05:37
If you want the . in your pattern to include the newline character use the /s modifier at the end of your pattern.
<?
$string1
= "<b>text</b>";
$string2 = "<b>te/nxt</b>";

// without the s
#output: something new
echo preg_replace("/<b>.*<//b>/", "something new", $string1);
#output: <b>te/nxt</b>
echo preg_replace("/<b>.*<//b>/", "something more new", $string2);

// with the s
#output: something new
echo preg_replace("/<b>.*<//b>/s", "something new", $string1);
#output: something new
echo preg_replace("/<b>.*<//b>/s", "something more new", $string2);
?>
syd_egan at hotmail dot com
28-Nov-2003 01:10
I have been working to improve the expressions to turn text urls into html hyperlinks, and eliminate the problem with very long urls causing formatting problems, without resorting to a link called "link".

I have written an expression to display only the host name  whilst linking to the full url:

$text = preg_replace( "`(http|ftp)+(s)?:(//)((/w|/.|/-|_)+)(/)?(/S+)?`i", "<a href=/"//0/" target=/"_blank/">//4</a>", $text);

Thus:

"More info can be found at http://www.php.net/manual/en/function.preg-match-all.php"

will become

"More info can be found at
<a href="http://www.php.net/manual/en/function.preg-match-all.php">
www.php.net</a>"

Hope this saves someone else re-inventing this wheel!!
nospam at home dot net
20-Nov-2003 11:09
replacing patterns with /b might yield to different results depending on your script platform. ex:
   $new = preg_replace("/bֳterreich/b/i","A","Germany ֳterreich France");
will replace on windows systems, but will not replace on linux etc., since '֧ will be interpreted as a '/b' itself.
jlyman at oregontech dot net
18-Nov-2003 05:29
I had some text with numbers that I wanted to use as array references in the replacement text- here's how it worked for me:

   $string="My name is [0]";
   $names=array("Bill","Bob","Joe");

   $string = preg_replace("//[(/d+)/]/",$names[(int) ${1}],$string);

   echo $string;

output should be "My name is Bill"...

Took me just a bit of playing around to figure this out (newbie), so I thought I would post it here.
Peter
01-Nov-2003 08:00
Suppose you want to match '/n' (that's backslash-n, not newline). The pattern you want is not ///n/ but /n/. The reason for this is that before the regex engine can interpret the // into /, PHP interprets it. Thus, if you write the first, the regex engine sees /n, which is reads as newline. Thus, you have to escape your backslashes twice: once for PHP, and once for the regex engine.
Travis
18-Oct-2003 06:37
I spent some time fighting with this, so hopefully this will help someone else.

Escaping a backslash (/) really involves not two, not three, but four backslashes to work properly.

So to match a single backslash, one should use:

preg_replace('/()/', ...);

or to, say, escape single quotes not already escaped, one could write:

preg_replace("/([^])'/", "/$1/'", ...);

Anything else, such as the seemingly correct

preg_replace("/([^//])'/", "/$1/'", ...);

gets evaluated as escaping the ] and resulting in an unterminated character class.

I'm not exactly clear on this issue of backslash proliferation, but it seems to involve the combination of PHP string processing and PCRE processing.
justhuda at netscape dot net
17-Jul-2003 11:41
REPLACE + ARRAYS

Sometimes you have string ini database field like this "1, 3, 6";
you have definition for the numbers in an array,
and you want to replace them and print.

This is the solution I found :

$string = "1, 3, 6";
$days=array(1 => "Monday","Sunday","Tuesday",
                 "Wednesday","Thursday","Friday","Saturday");
print preg_replace("/([1-6])/e","/$days['//1']",$string);

result : "Monday, Tuesday, Friday";
toxic79_spam at yahoo dot com
10-Feb-2003 08:45
here's another way to link urls in text. unlike the others i see here, this one doesn't link urls that have already been linked so you won't get <a href="<a href="http://www.blah.com">http://www.blah.com</a>">link</a> if your text ($txt) already has links in it.

it's been quickly tested with uppercase, lowercase, http and ftp, secure urls, ports and query strings. it won't work if the url has spaces in it, but if you convert them to %20 it'll be ok.

$txt = preg_replace( "/(?<!<a href=/")((http|ftp)+(s)?:[^<>/s]+)/i", "<a href=/"//0/">//0</a>", $txt );
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值