tags:

views:

105

answers:

2

I have a problem with my RegEx. I want to translate a BBCode Link like

[link=www.stackoverflow.com]Stack-Overflow[/link]

into a HTML Link like

<a href='www.stackoverflow.com'>Stack-Overflow</a>.

In my String it's possibile to make more than one link in BBCode. I Also need a function to translate the html back to BBCode.

My functions are BBCode To HTML:

$Text = preg_replace('/\[link=([^ ]+).*\](.*)\[\/link\]/', '<a href="$1">$2</a>', $Text);  

HTML To BBCode:

$Text = preg_replace('/\<a href="([^ ]+).*\">(.*)\<\/a\>/Usi', '[link=$1]$2[/link]', $Text); 

My Problem is with thees functions, when i have more than one Link, it doesn't work, and when i have one Link translated to HTML and i want to translate back, i have only the first character of the link.

Can everyone help me? thanks in advance

+5  A: 

As for your first problem, * is greedy, so it catches everything between the first and last links. A simple solution is to use a non-greedy qualifier, or to not allow [] in your groups:

\[link=([^ \[\]]+)\]([^\[\]]*)\[\/link\]

Similarly, for the other way around:

<a href="([^ "]+)">([^<]*?)\<\/a\>

Here's the non-greedy version. It allows [] in links, and is even shorter:

\[link=([^ ]*?)\](.*?)\[\/link\]
Kobi
Tor Valamo
Good point. Thanks, Tor.
Kobi
thanks for your help. it was very useful. It works perfect.
snuffer.ch
A: 

Your problem is with the greedy .* Use ? to make it non greedy.

$Text = preg_replace(
    '/\[link=([^ ]+).*?\](.*?)\[\/link\]/',
    '<a href="$1">$2</a>',
    $Text
);
slebetman
it has to be inside the parens, otherwise it does something completely different.
Tor Valamo
Whoops, yes my bad. Edited to correct mistake.
slebetman