Question

I'm trying to convert all instances of the > character to its HTML entity equivalent, >, within a string of HTML that contains HTML tags. The furthest I've been able to get with a solution for this is using a regex.

Here's what I have so far:

        public static readonly Regex HtmlAngleBracketNotPartOfTag = new Regex("(?:<[^>]*(?:>|$))(>)", RegexOptions.Compiled | RegexOptions.Singleline);

The main issue I'm having is isolating the single > characters that are not part of an HTML tag. I don't want to convert any existing tags, because I need to preserve the HTML for rendering. If I don't convert the > characters, I get malformed HTML, which causes rendering issues in the browser.

This is an example of a test string to parse:

"Ok, now I've got the correct setting.<br/><br/>On 12/22/2008 3:45 PM, jproot@somedomain.com wrote:<br/><div class"quotedReply">> Ok, got it, hope the angle bracket quotes are there.<br/>><br/>> On 12/22/2008 3:45 PM, > sbartfast@somedomain.com wrote:<br/>>> Please someone, reply to this.<br/>>><br/>><br/></div>"

In the above string, none of the > characters that are part of HTML tags should be converted to >. So, this:

<div class"quotedReply">>

should become this:

<div class"quotedReply">&gt;

Another issue is that the expression above uses a non-capturing group, which is fine except for the fact that the match is in group 1. I'm not quite sure how to do a replace only on group 1 and preserve the rest of the match. It appears that a MatchEvaluator doesn't really do the trick, or perhaps I just can't envision it right now.

I suspect my regex could do with some lovin'.

Anyone have any bright ideas?

Was it helpful?

Solution

The trick is to capture everything that isn't the target, then plug it back in along with the changed text, like this:

Regex.Replace(str, @"\G((?>[^<>]+|<[^>]*>)*)>", "$1&gt;");

But Anthony's right: right angle brackets in text nodes shouldn't cause any problems. And matching HTML with regexes is tricky; for example, comments and CDATA can contain practically anything, so a robust regex would have to match them specifically.

OTHER TIPS

Why do you want to do this? What harm are the > doing? Most parsers I've come across are quite happy with a > on its own without it needing to be escaped to an entity.

Additionally, it would be more appropriate to properly encode the content strings with HtmlUtilty.HtmlEncode before concatenating them with strings containing HTML markup, hence if this is under your control you should consider dealing with it there.

Maybe read your HTML into an XML parser which should take care of the conversions for you.

Are you talking about the > chars inside of an HTML tag, (Like in Java's innerText), or in the arguements list of an HTML tag?

If you want to just sanitize the text between the opening and closing tag, that should be rather simple. Just locate any > char, and replace it with the &gt ;. (I'd also do it with the &lt tag), but the HTML render engine SHOULD take care of this for you...

Give an example of what you are trying to sanitize, and maybe we an find the best solution for it.

Larry

Could you read the string into an XML document and look at the values and replace the > with &gt; in the values. This would require recursively going into each node in the document but that shouldn't be too hard to do.

Steve_C, you may try this RegEx. This will give capture any HTML tags in reference 1, and the text between the tags is stored in capture 2. I didn't fully test this, just throwing it out there in case it might help.

<([A-Z][A-Z0-9]*)[^>]*>(.*?)</\1>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top