Regular Expressions: preg_replace only does one per line.

Posted on 2004-11-17
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

$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?
Question by:KvdnBerg
    LVL 48

    Accepted Solution

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

    notify the /U for ungreedy match of preg_replace
    LVL 3

    Author Comment

    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.
    LVL 10

    Assisted Solution

    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)


    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.

    LVL 3

    Author Comment

    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);


    LVL 48

    Expert Comment

    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.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
    Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
    The viewer will learn how to dynamically set the form action using jQuery.
    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…

    737 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

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now