Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP RegEx: matching a word or sentence inside a html <p> BUT NOT inside <div> <img> <a> tags

Tags:

html

regex

php

I'm trying to match and replace about 100 words inside an html document creating links for each word. For performance reasons, I think DOM manipulation will be slower than preg_replace.

The thing is I want to be able to match (and replace) just simple words (or sentences)

INSIDE <p> tags BUT NOT inside any other tag <a> <div> nor <img>.

I'm using this regex expression to match the word "sapien":

/(<p[^>]*>)(.*)(?!<a\s[^>]+>[^<\/a>]+)(?!=\"[\w]*)(\bsapien\b)(?![^<\/a>]+<\/a>)(?![^\w]*\")(.*)(<\/p>)/imU

Here is the text where I'm applying it:

<p>Cras cursus consequat nibh <a href="#">sapien</a>ac vehicula. Sed erat sapien, condimentum quis risus nec, viverra dignissim nisi. Cras sapien convallis, erat egestas tincidunt <img src="myimage.jpg" alt="sapien" >rutrum, massa enim sagittis ante, sed pellentesque lorem risus vitae enim. Curabitur hendrerit dolor facilisis <a href="sapien">sapien</a> dolor malesuada molestie.</p>

I'm getting the match in

<a href="#">sapien</a> 

which is inside tag.

Any help will be much appreciated. Thanks.

like image 641
Mike Alvim Avatar asked Dec 08 '25 14:12

Mike Alvim


1 Answers

Solution in just one step, with negative lookahead:

preg_replace("#\b(sapien)\b(?![^<>]*(<\/a|<\/div|>))#i", "<a href='#'>\\1</a>", $input);

Demo: http://ideone.com/Z74X0f

With non-fixed width lookaround pattern we can only use lookahead (lookbehind doesn't work in that way), so we check for the presence of closing tags after our string.

Current regexp works good on example text, but may have some issues with nested tags. For example, if before ending tag will be any other tag, like here <div> sapien <img></div> it will also apply the replacement to that piece.

You can avoid this by adding extra variations to regexp:

\b(sapien)\b(?!([^<>]*(<img[^>]+>)[^<>]*|[^<>]*)(<\/a|<\/div|>))

Demo: https://regex101.com/r/a5JiOo/2

like image 79
Evgeniy Maynagashev Avatar answered Dec 11 '25 04:12

Evgeniy Maynagashev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!