Forum Moderators: coopster

Message Too Old, No Replies

simple regex question

         

RyanM

4:17 am on Mar 6, 2006 (gmt 0)

10+ Year Member



Hi,
I am writing a function for converting BBCode style markup to HTML, its a good way to learn regex and to also stop users from spoiling styling with pesky WYSIWYGS, the idea is to make the markup as easy as possible so things like [heading]this is my heading[/heading], [link=http://www.com]this is my link[/link] are used; as well as single line breaks are converted to <br> amd double line breaks to </p><p>, etc however I am now stuck on lists. I want the format to be similar to the above mentioned paragraph break (ie to line breaks = a new paragraph), the difference being that a double line break within the [list]...[/list] tags will be changed to </li><li> instead of </p><p>.

Now to do this I need to either find the double line break within the [list] tags and convert it to </li><li> or find the </p><p>, finding these characters is obviously no problem but I am having trouble isolating them within the [list]...[/list] tags.

The markup will be similar to this:

[list]
item 1

item 2

item 3
[/list]

and should output

<ul>
<li>item 1</li>
<li>item l</li>
<li>item 1</li>
</ul>

Ok so the way to do this would be to have:

$text = preg_replace("/\[list\](.*?)\[\/list\]/s", "<ul>$1</ul>", $text);

This will create:

<ul>
item 1

item 2

item 3
</ul>

What I need is for someone to point me into the right direction for writing regex's like the following:

/\[list\].*\r\n.*\[\/list\]/s, "</li><li>" where only the \r\n (or \r\n\r\n as in the example it doesnt really matter) is replaced.

Thanks,

- Ryan

DrDoc

4:44 am on Mar 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You probably want to use preg_replace_callback() [php.net]

function dostuff($str) {
return "<ul>" . preg_replace(array("/^\s+/s", "/(.*?)(\r?\n)+/gs"), array("", "<li>$1</li>"), $str . "\r\n") . "</ul>";
}
$text = preg_replace("/\[list\](.*?)\[\/list\]/s", "dostuff", $text);

dreamcatcher

9:08 am on Mar 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Another alternative:

function convert($data)
{
$data = eregi_replace(quotemeta("[*ul]"), quotemeta("<ul>"), $data);
$data = eregi_replace(quotemeta("[*/ul]"), quotemeta("</ul>"), $data);
$data = eregi_replace(quotemeta("[*li]"), quotemeta("<li>"), $data);
$data = eregi_replace(quotemeta("[*/li]"), quotemeta("</li>"), $data);

return $data;

}

Note: stars added to prevent formatting

dc

RyanM

11:07 pm on Mar 6, 2006 (gmt 0)

10+ Year Member



Thanks Dr Doc that worked a wonder

For anyone else that may need this functionality it is important to return the 0 index of the matches array, for instance (this is not my code but a simplified version for illustration purposes):

function callBack($text) {
$text = str_replace("\r\n","</li><li>");
return $text[0]; //I return 0 as this is the complete match, $text[1] is the first match, etc.
}

echo preg_replace_callback("/\[list\](.*?)\[\/list\]/s", "callBack", $subject);

- Ryan