lc Posted June 20, 2010 Share Posted June 20, 2010 Hi there! First of all, let me apologise if I'm repeating the question (that would be odd, given the question) and for any other inconveniences (if any, please tell me!). Now, straight to the point. :-) I'm a newbie to regex, and here's what I'm trying and failing to do: I'm trying to have a long text analysed and insert some links when some strings are found (extracted form a db). I've got this: $text = 'The Adventure Company did a fine job'; while($variable= $results->fetch_assoc()) { $pattern = '#(<p>|[^->a-zA-Z0-9áéíóúÁÉÍÓÚñÑ])' . preg_quote($variable['name'], '#') . '(?![^>]*?<)(</p>|[^-<a-zA-Z0-9a-zA-Z0-9áéíóúÁÉÍÓÚñÑ])#i'; $replacement = '$1<a href="page.php?id=1">' . $variable['name'] . '</a>$2'; if(preg_match($patron, $cuerpo)) { $text = preg_replace($pattern, $replacement, $text); } If $variable['name'] take as values "The Adventure Company" and "job", everything's rigth and the result is: <a href="page.php?id=1">The Adventure Company</a> did a fine <a href="page.php?id=1">job</a> Then, if $variable['name'] take as values "The Adventure Company" and "adventure", the result is: <a href="page.php?id=1">The <a href="page.php?id=1">Adventure</a> Company</a> did a fine job Which obviously breaks the links. The result I'd like to get when the values are passed in the order "The Adventure Company", "adventure" is: <a href="page.php?id=1">The Adventure Company</a> did a fine job So that adventure isn't replaced by a link again. Is there any way I can make a pattern for getting the job done in both variable cases? I hope I explained myself. Regards, and thanks in advance. Quote Link to comment Share on other sites More sharing options...
lc Posted June 21, 2010 Author Share Posted June 21, 2010 So sorry, the pattern I'm using is this one: $pattern = '#(<p>|[^->a-zA-Z0-9áéíóúÁÉÍÓÚñÑ])' . preg_quote($variable['name'], '#') . '(</p>|[^-<a-zA-Z0-9áéíóúÁÉÍÓÚñÑ])#i'; I was doing tests and I copied the wrong one. Quote Link to comment Share on other sites More sharing options...
salathe Posted June 21, 2010 Share Posted June 21, 2010 A common approach would be to perform a two-step replacement. On the first pass, replace the matching strings with some value that will serve as a placeholder. On the second pass, replace those placeholders with the HTML replacement that you want. It would be possible to check for the existence of the anchor tag wrapping the string, so everything could be done in one replacement (as you are currently doing) but that might turn what is currently a complicated, messy regex into something even more complicated and messy. Since you're currently running through the replacements one-at-a-time in the order that they come from in the database query, are you concerned at all about matching the longest phrase first (so "The Adventure Company" will always get replaced in preference to "adventure")? Quote Link to comment Share on other sites More sharing options...
lc Posted June 21, 2010 Author Share Posted June 21, 2010 Thanks for the answer! I'm trying what you suggest, that's a good idea. I'll have to put another while there, but it's really a very fast operation so it'll be as effective as just one. In fact, the matching strings from the db are ordered by lenght, but if I don't replace with the placeholder your suggestion when it reaches the smaller string there's an overlap. If I replace with a placeholder, there won't be any overlap and I'll get exatly what I want! This should have come to my mind, your's the merit. :-) I'm getting it done and let you know the result! Thanks. Quote Link to comment Share on other sites More sharing options...
lc Posted June 21, 2010 Author Share Posted June 21, 2010 It does the job perfectly, salathe. Thanks a lot, really. :-) Quote Link to comment Share on other sites More sharing options...
salathe Posted June 21, 2010 Share Posted June 21, 2010 No worries. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.