0

Similar to what's here and many other places on stackoverflow, but with a twist.

Say I have the sentence "I like brown dogs." on my page. I want to process this text before it's output and look for the word brown. If brown is already part of a link (wrapped in an A tag) then do nothing. However if it is not in a link, use my pre-defined code as a replacement.

My code would be something like this:

<a href="/brown" title="Looking for the color brown?">brown</a>

It would be best if the original case of the word didn't change either.

I'd like this to be an array I can specify, such as:

$links = array("brown" => array("/brown" => "Looking for the color brown?"));

I don't even know if I explained well enough, or if it's possible, but if it is, please let me know. Thanks!

Edit: I found one close to what I want, and got it to work somewhat. Find the code here. The problem is I can't limit the number of replacements, such as only do it once per page, or twice per page. Ideally I'd like to tell it to ignore it if it's in H tags. Hi milki_.

Community
  • 1
  • 1
  • possible duplicate of [Regex to match words or phrases in string but NOT match if part of a URL or inside tags. (php)](http://stackoverflow.com/questions/6009415/regex-to-match-words-or-phrases-in-string-but-not-match-if-part-of-a-url-or-insi) or [Regular expression replace a word by a link](http://stackoverflow.com/questions/276029/regular-expression-replace-a-word-by-a-link) – mario Oct 22 '11 at 03:11
  • By the way, you can easily add a limit to the number of replacements to the answer you linked to, or any other `preg_replace`. See the `limit` argument at http://php.net/manual/en/function.preg-replace.php – John Flatness Oct 22 '11 at 04:13
  • Yes, I found the limit argument, that's why I deleted that from my original question. The difference between my question and any other one I can find here (and I've read about 15) is making sure it's not in a certain type of tag, such as blockquote, or H3. – user1004207 Oct 22 '11 at 04:48

1 Answers1

0

If you want to rewrite HTML context-aware, then it's in fact easier to just resort to DOM functions. You'd still need the regex or string functions to rewrite the text nodes, so it would be way more code.

But a simple workaround to get the desired effect would be to use preg_replace_callback. Simply match the undesired tags too, and then ignore them in the callback.

preg_replace_callback('%(<h)\d>.*?</h\d>|Amazon(?![^<]*</a>)%si',
                      'replace_cb_words', ...

function replace_cb_words($match) {

     // ignore the <h1>... matches
     if ($match[1]) return $match[0];

     // rewrite the words otherwise:
     return "<a ...>$match[0]</a>";
}
mario
  • 144,265
  • 20
  • 237
  • 291