views:

2550

answers:

8

I am trying to write a regular expression to strip all HTML with the exception of links (the <a href and </a> tags respectively. It does not have to be 100% secure (I am not worried about injection attacks or anything as I am parsing content that has already been approved and published into a SWF movie).

The original "strip tags" regular expression I'm using was <(.|\n)+?>, and I tried to modify it to <([^a]|\n)+?>, but that of course will allow any tag that has an a in it rather than one that has it in the beginning, with a space.

Not that it should really matter, but in case anyone cares to know I am writing this in ActionScript 3.0 for a Flash movie.

A: 

How about

<[^a](.|\n)+?>

?

Jimmy
A: 

@Jimmy: Close, this will prevent the starting a from being stripped, but not the closing a.

Jeff Winkworth
You should've probably posted a comment on his answer instead.
Andreas Bonini
SO didn't have comments in September 2008.
Jeff Winkworth
+5  A: 
<(?!\/?a(?=>|\s.*>))\/?.*?>

Try this. Had something similar for p tags. Worked for them so don't see why not. Uses negative lookahead to check that it doesn't match a (prefixed with an optional / character) where (using positive lookahead) a (with optional / prefix) is followed by a > or a space, stuff and then >. This then matches up until the next > character. Put this in a subst with

s/<(?!\/?a(?=>|\s.*>))\/?.*?>//g;

This should leave only the opening and closing a tags

Xetius
A: 

@Xetius: Worked brilliantly! Thanks!

update: One minor tweak is required for AS3 implementation: <(?!\/?a(?=>|\\s.*>))\/?.*?>

That's a \\s, instead of a \s

Jeff Winkworth
A: 

I keep going on about it, but there's no way I can recommend regexr too often. It's fantastic for testing this type of things.

grapefrukt
A: 

@grapefrukt: I'm actually a regular user of RegExBuddy, but I couldn't figure out the excluding a tag. ;-)

Jeff Winkworth
A: 

In general there are problems with this approach. Regexes are best for 'flat' text matches - nested data pushes regex engines into areas for which they are not designed. General HTML parsing needs a parser not a regex engine (Google for the difference between regular and context-free languages if you want the full technical details).

It is easy to strip out all tags by replacing /</ and />/ with the empty string or their entity equivalents but selectively filtering HTML using regexes will be vulnerable to a wide range of accidental or malicious inputs breaking things.

domgblackwell
A: 

Here you go:

{<(?!i|b|h[1-6]|/i|/b|/h[1-6][\s|>|/])[^>]*>}
Qamar