Parsing markup with regex is like building your house using lego... it's not the right tool for the job. HTML is not _a regular language_, therefore _regular_ expressions don't cut the mustard.<br/> What you need is a DOM parser, and as luck would have it, PHP has the `DOMDocument` object, which is just that: $dom = new DOMDocument; $dom->loadHTML('<img onload="alert(\'hello world\');" onclick="alert(\'hello world\');" />'); $nodes = $dom->getElementsByTagName('*');//just get all nodes, //$dom->getElementsByTagName('img'); would work, too foreach($nodes as $node) { if ($node->hasAttribute('onload')) { $node->removeAttribute('onload'); } if ($node->hasAttribute('onclick')) { $node->removeAttribute('onclick'); } } echo $dom->saveHTML();//will include html, head, body tags and doctype Tadaa... both `onload` and `onclick` have been removed from the markup, without the pain of writing a reliable and stable regex, that can deal with in-line JS... As an added bonus, this code will be far more maintainable (and expandable) in the future. I'd much prefer maintaining this code, than having to rework a regular expression somebody wrote a couple of months ago... If you want, you can echo only the tags you've changed, like so: $changed = array(); $attributesOfDeath = array('onload', 'onclick'); foreach($nodes as $node) { $current = null; foreach($attributesOfDeath as $attr) { if ($node->hasAttribute($attr)) { $node->removeAttribute($attr); $current = $node; } } if ($current) { $changed[] = $current;//add to changed array } } $changed = array_map(array($dom, 'saveXML'), $changed); echo implode(PHP_EOL, $changed); As Jan said, for maintainability it's best to use an array of _"forbidden attributes"_. That's what the `$attributesOfDeath` array is for. If you want to, later on, check for a third or fourth attribute, you can simply add that to the array, and nothing else in your code need change. It'll just keep on working as before.