up vote 1 down vote favorite

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

flag
I'd recommend regular expressions, but then you'd have two problems. ;) – musicfreak Jul 2 '09 at 4:28
2  
i thought that ` was a back tick and \ was a backslash? – Mike Cooper Jul 2 '09 at 5:52
Yes, a ` is a backtick and \ is a backslash, but I was trying to escape it. I figured Stack Overflow would parse them... :) – redwall_hp Jul 3 '09 at 3:54

2 Answers

up vote 2 down vote accepted

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.

link|flag
I ended up using this one: $readme = preg_replace('/*(.*?)*/', '<em>\\1</em>', $readme); – redwall_hp Jul 3 '09 at 4:21
up vote 1 down vote

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>";
}
link|flag

Your Answer

get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.