views:

644

answers:

2

Okay, here's what I'm trying to do: I'm trying to use PHP to develop what's essentially a tiny subset of a markdown implementation, not worth using a full markdown class.

I need essentially do a str_replace, but alternate the replace string for every occurrence of the needle, so as to handle the opening and closing HTML tags.

For example, italics are a pair of asterisks like *this*, and code blocks are surrounded by backticks like \this\.

I need to replace the first occurrence of a pair of the characters with the opening HTML tag corresponding, and the second with the closing tag.

Any ideas on how to do this? I figured some sort of regular expression would be involved...

+2  A: 

Personally, I'd loop through each occurrence of * or \ with a counter, and replace the character with the appropriate HTML tag based on the count (for example, if the count is even and you hit an asterisk, replace it with <em>, if it's odd then replace it with </em>, etc).

But if you're sure that you only need to support a couple simple kinds of markup, then a regular expression for each might be the easiest solution. Something like this for asterisks, for example (untested):

preg_replace('/\*([^*]+)\*/', '<em>\\1</em>', $text);

And something similar for backslashes.

musicfreak
I ended up using this one:$readme = preg_replace('/\*(.*?)\*/', '<em>\\1</em>', $readme);
redwall_hp
+1  A: 

What you're looking for is more commonly handled by a state machine or lexer/parser.

This is ugly but it works. Catch: only for one pattern type at a time.

$input = "Here's some \\italic\\ text and even \\some more\\ wheee";

$output = preg_replace_callback( "/\\\/", 'replacer', $input );

echo $output;

function replacer( $matches )
{
    static $toggle = 0;
    if ( $toggle )
    {
     $toggle = 0;
     return "</em>";
    }
    $toggle = 1;
    return "<em>";
}
Peter Bailey