views:

71

answers:

3

I use regex to create html tags in plain text. like this

loop

$SearchArray[] = "/\b(".preg_quote($user['name'], "/").")\b/i"; 
$ReplaceArray[] = '<a href="'.$user['url'].'">$1</a>';

-

$str = preg_replace($SearchArray, $ReplaceArray, $str);

I'm looking for a way to not match $user['name'] in a tag.

+2  A: 

You could use preg_replace_callback()

for 5.3+:

$callback = function($match) using ($user) {
    return '<a href="'.$user['url'].'">'.$match[1].'</a>';
};
$regex = "/\b(".preg_quote($user['name'], "/").")\b/i"; 
$str = preg_replace_callback($regex, $callback, $string);

for 5.2+:

$method = 'return \'<a href="'.$user['url'].'">\'.$match[1].\'</a>\';';
$callback = create_function('$match', $method);
$regex = "/\b(".preg_quote($user['name'], "/").")\b/i"; 
$str = preg_replace_callback($regex, $callback, $string);
ircmaxell
I have never used a callback like this in php. i'm using php 5.2.. can i put this code in the loop and loop for 200 times?
Remi
You could... Performance may be an issue (You might be better off with `str_ireplace()`, but you won't be able to keep the case of the name)...
ircmaxell
i still have problems with to get a working loop in php 5.2. the error is "syntax error, unexpected '<' in on runtime-created function".The $method and $regex are different every time. Coud you gif me a example of your code inside a loop?
Remi
+1  A: 

So the problem is that you're making several passes over the document, replacing a different user name in each pass, and you're afraid you'll unintentionally replace a name inside a tag that was created in a previous pass, right?

I would try to do all of the replacements in one pass, using preg_replace_callback as @ircmaxwell suggested, and one regex that can match any legal user name. In the callback function, you look up the matched string to see if it's a real user's name. If it is, return the generated link; if not, return the matched string for reinsertion.

Alan Moore
Correct.Could you show me a example? I'm using php 5.2
Remi
What are the restrictions on user names? Which characters are legal? Is there a minimum or maximum length requirement? Is there a further restriction on the first character? For example, does the name have to start with a letter? We need that info in order to create the regex.
Alan Moore
the regex "/\b(".preg_quote($user['name'], "/").")\b/i" works for me speed is not important. There are also other word i want to match with there own regex.
Remi
Okay, but what I'm trying to do is create a regex that will match any valid user name, and (as much as possible) *not* match anything else.
Alan Moore
Just match the regex for that username. not anything else. And loop the regex.
Remi
A: 

It looks like you're trying to add a bunch of anchors to a document. Have you thought of using SimpleXML. This assumes that the anchor tags are part of a larger xhtml document.

//$xhtml_doc is some xhtml doc's path
$doc = simplexml_load_file($xhtml);
//NOTE: find the parent element for all these anchors (maybe with xpath)
//example: $parent = $doc->xpath('//div[@id=parent]');
foreach($user as $k => $v){
    $anchor = $doc->addChild('a', $v['name']);
    $anchor->addAttribute('href', $v['url']);
}
return $doc->asXML();

simpleXML helps me a lot in these situations. It'll be a lot faster than regex, even if this isn't exactly what you want to do.

Tim