tomerg3 Posted July 18, 2007 Share Posted July 18, 2007 I am using this code to convert a email@email.com to < a href="mailto: .."> I want to modify it so if there's also an active link < a href="mailto:...> in the text, it will not be changed My current code is: $text = eregi_replace("([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})","><a href=\"mailto:\\1\">\\1</a>", $text); Help please. Quote Link to comment Share on other sites More sharing options...
Wildbug Posted July 18, 2007 Share Posted July 18, 2007 One solution is to remove the already-linked e-mail addresses, then replace what's left. I do this by replacing them with a special piece of bookmark code containing the index of the array where I've saved them, replace the remaining e-mails, and then return the "stored" strings to their places. <?php function _pcre_emails ($txt,&$array_ref,&$counter_ref) { $array_ref[$counter_ref] = str_replace('\"','"',$txt); return '<?php' . $counter_ref++ . '?' . '>'; } // (Separated ? and > above so PHP highlighting would work, but not necessary in code) $emails = array(); $email_counter = 0; $text = 'I am using this code to convert a email@email.com to <a href="mailto:user@example.com">user@example.com</a>'; echo "\n",htmlentities($text),"\n"; echo htmlentities(preg_replace( array( '/(<a href="mailto:.*?">.*?<\/a>)/ie', '/([\w.-]+@(?:[\w-]+\.){1,3}\w{2,4})/i', '/<\?php(\d+)\?\>/e'), // Escaped the \>, but not necessary, same reason array( '_pcre_emails(\'$1\',$emails,$email_counter)', '<a href="mailto:$1">$1</a>', '$emails[$1]'), $text)),"\n"; ?> OUTPUT: I am using this code to convert a email@email.com to <a href="mailto:user@example.com">user@example.com</a> I am using this code to convert a <a href="mailto:email@email.com">email@email.com</a> to <a href="mailto:user@example.com">user@example.com</a> Quote Link to comment Share on other sites More sharing options...
tomerg3 Posted July 18, 2007 Author Share Posted July 18, 2007 One solution is to remove the already-linked e-mail addresses, then replace what's left. I do this by replacing them with a special piece of bookmark code containing the index of the array where I've saved them, replace the remaining e-mails, and then return the "stored" strings to their places. <?php function _pcre_emails ($txt,&$array_ref,&$counter_ref) { $array_ref[$counter_ref] = str_replace('\"','"',$txt); return '<?php' . $counter_ref++ . '?' . '>'; } // (Separated ? and > above so PHP highlighting would work, but not necessary in code) $emails = array(); $email_counter = 0; $text = 'I am using this code to convert a email@email.com to <a href="mailto:user@example.com">user@example.com</a>'; echo "\n",htmlentities($text),"\n"; echo htmlentities(preg_replace( array( '/(<a href="mailto:.*?">.*?<\/a>)/ie', '/([\w.-]+@(?:[\w-]+\.){1,3}\w{2,4})/i', '/<\?php(\d+)\?\>/e'), // Escaped the \>, but not necessary, same reason array( '_pcre_emails(\'$1\',$emails,$email_counter)', '<a href="mailto:$1">$1</a>', '$emails[$1]'), $text)),"\n"; ?> OUTPUT: I am using this code to convert a email@email.com to <a href="mailto:user@example.com">user@example.com</a> I am using this code to convert a <a href="mailto:email@email.com">email@email.com</a> to <a href="mailto:user@example.com">user@example.com</a> That's way way too long, I figured it out with some help on another forum, try this, it's much cleaner.... $text = preg_replace("~(?>[\w.-]+@[\w.-]+)(?!</a>)(?!\">)~","<a href=\"mailto:\\0\">\\0</a>", $text); Thanks anyway. Quote Link to comment Share on other sites More sharing options...
effigy Posted July 18, 2007 Share Posted July 18, 2007 That will work as long as href is always the last attribute in the tag. (Does the \0 really work?) Quote Link to comment Share on other sites More sharing options...
Wildbug Posted July 18, 2007 Share Posted July 18, 2007 Ah, the once-only subpattern operator... that's what I needed. I started replying with a simple lookbehind regex, but while it would ignore user@example.com it would then find ser@example.com since "s" wasn't preceeded by the "mailto:" bit. So, thanks, I learned about the once-only operator. Also, $text = preg_replace('~(?<!href="mailto:|>)(?>[\w.-]+@(?:[\w-]+\.){1,3}[a-z]{2,6})(?!">|</a>)~i','<a href="mailto:$0">$0</a>', $text); ($0 preferred to \\0; neg. lookaheads can be collapsed; double to single quotes) 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.