[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Regular Expressions: preg_replace only does one per line.

Posted on 2004-11-17
5
Medium Priority
?
335 Views
Last Modified: 2012-06-22
I am writing a little hack for a Wiki that enables highlighting of text using a background color. I use preg_replace to replace text delimited by ++ to insert the appropriate span. It works fine except for one thing, when there are multiple words highlighted in the same line, it only replaces the first and the last ++, leaving the middle ones intact and in effect it highlights the whole line from the first ++ to the last (with ++ as plain text in the middle). Here's the sample code

<?php
$text = "test  ++highlight!!++ test test test ++test++ highlight";

echo preg_replace('/\+\+(.*)\+\+/','<span style="background-color: #FFFF00">\\1</span>', $text);
?>

In this case, the first occurence of "highlight" and the last occurence of "test" should be highlighted (ie <span...>highlight</span>). If I insert a \n between the two words somewhere it works as it should.

I am not much of a regular expressions expert so could someone help me fix this one?
0
Comment
Question by:KvdnBerg
  • 2
  • 2
5 Comments
 
LVL 48

Accepted Solution

by:
hernst42 earned 800 total points
ID: 12603749
Try
echo preg_replace('/\+\+(.*)\+\+/U','<span style="background-color: #FFFF00">\\1</span>', $text);

notify the /U for ungreedy match of preg_replace
0
 
LVL 3

Author Comment

by:KvdnBerg
ID: 12603818
Perfect, works like a charm but could you please explain in a little more detail why this works?
I usually just copy&paste regex things and adapt them without really understanding them.
0
 
LVL 10

Assisted Solution

by:frugle
frugle earned 200 total points
ID: 12604583
preg_replace('/   #start
\+                      # escaped + matches a real +
\+                      # escaped + matches a real +
(.*)                    # everything up to the next match
\+                      # escaped + matches a real +
\+                      # escaped + matches a real +
/                        #stop
',

'replace with',                                    # \\1 is the contents of the first set of (brackets)

$variable_to_replace_in);

so, in English - look for the first two instances of the plus sign together then read everything until the next set of two plus signs.

Without the /U un-greedy flag, it sees the first and last double-plusses and highlights EVERYTHING in between them.

Mike
0
 
LVL 3

Author Comment

by:KvdnBerg
ID: 12604597
Ok. I did some searching and found out myself. Normally PERL regular expressions are 'greedy', meaning they try to make the longest match possible. The U at the end of hernst42's answer means "ungreedy" so that it makes the shortest match possible. This can also be accomplished by putting a ? after the wildcard (*) like so:

echo preg_replace('/\+\+(.*?)\+\+/','<span style="background-color: #FFFF00">\\1</span>', $text);

See http://www.troubleshooters.com/codecorn/littperl/perlreg.htm#Greedy

0
 
LVL 48

Expert Comment

by:hernst42
ID: 12604717
See http://de3.php.net/manual/en/reference.pcre.pattern.modifiers.php
the greedyness/ungreedines defines how many chars are used if * are given. The default is to match as many chars as along as the regex matches. If you use ungreedines it tries to match that expression with the minum characters.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses
Course of the Month20 days, 6 hours left to enroll

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question