3

I am using the PHP and Regex below to search through a huge string for

[LINK]www.anyurl.com[/LINK]

and replace it with:

<a href="http://www.anyurl.com">http://www.anyurl.com</a>

The http:// is prepended if http or ftp do not exist in front of the url already.

$re = '/\[LINK]((?:(?!(http|ftp)|\[\/LINK]).)*)\[\/LINK]/i'; 
$subst = '[LINK]http://$1[/LINK]'; 
$xtext = preg_replace($re, $subst, $xtext, 1);
$xtext = preg_replace("/(\[LINK\])(\S*)(\[\/LINK])/", "<a href=\"$2\" target='_blank'>$2</a>", $xtext);

My problem is it only appears to be working for the first match it comes to and not other [LINK]www.urls.com[/LINK] in the document. The document being $xtext

13
  • 5
    I am none the wiser now but thanks for commenting Commented May 30, 2014 at 22:20
  • 2
    @developerwjk I am not parsing HTML tags. When did [LINK] [/LINK] become a HTML tag? Commented May 30, 2014 at 22:26
  • 1
    @MikeC people here can be ignorant and just regex haters. Commented May 30, 2014 at 22:27
  • 1
    @MathewFoscarini I wouldn't mind but they could provide a solution rather than just saying what they say. The solution I have above is fast and works well but i need it to repeat. I expect those that attack don't actually understand what they are seeing. Commented May 30, 2014 at 22:30
  • 2
    PHP has a BBCode built-in extension. Commented May 30, 2014 at 22:53

3 Answers 3

1

Whoops, I have just found my error and it is so simple. In my third line:

$xtext = preg_replace($re, $subst, $xtext, 1);

I have 1 at the end of the preg_replace i.e. replace once. This should be set to -1 or left blank to replace all.

Sign up to request clarification or add additional context in comments.

Comments

0

I think your problem could be the greedyness of your first regex. As you prepend the http:// to your first found link, all other links will stay the same. So please try (note the additional questionmark in line one):

$re = '/\[LINK]((?:(?!(http|ftp)|\[\/LINK]).)*?)\[\/LINK]/i'; 
$subst = '[LINK]http://$1[/LINK]'; 
$xtext = preg_replace($re, $subst, $xtext);
$xtext = preg_replace("/(\[LINK\])(\S*)(\[\/LINK])/", "<a href=\"$2\" target='_blank'>$2</a>", $xtext);

Comments

0

In the first expression the 1 needed to be removed, as you already figured out. Notice the second expression is the same as your second expression but with * replaced with +?, and the unnecessary capture groups around the tags removed. * doesn't stop at the first [\LINK] but at the last one, resulting in a link with display text like http://www.google.com[/LINK]\n[LINK]http://www.yahoo.com so +? is needed.

$xtext = '[LINK]www.google.com[/LINK]\n[LINK]www.yahoo.com[/LINK]';

$re = '/\[LINK]((?:(?!(http|ftp)|\[\/LINK]).)*)\[\/LINK]/i';
$subst = '[LINK]http://$1[/LINK]';
$xtext = preg_replace($re, $subst, $xtext, 1);

$xtext = preg_replace("/\[LINK\](\S+?)\[\/LINK]/", "<a href='$1' target='_blank'>$1</a>", $xtext);

3 Comments

You are not checking if the link has http or ftp prepended to it in the first place. Mine checks if the link is [LINK]www.example.com[/LINK] or [LINK]example.com[/LINK] and if it is the former prepends http:// to it.
@developerwjk Your expression substituting my (\S*) for your (\S+?) takes 58 iterations while mine takes 32. I'll stick with mine. I don't see where you have rationalised the capture groups in your example??? Anyway I solved the issue, you started off abusive, have given me 2 incorrect answers so we will leave it there.
@MikeC, Abusive? I was explaining j_mcnally's comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.