Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert > to HTML entity equivalent within HTML string

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, [email protected] wrote:<br/><div class"quotedReply">> Ok, got it, hope the angle bracket quotes are there.<br/>><br/>> On 12/22/2008 3:45 PM, > [email protected] 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?

like image 626
steve_c Avatar asked Mar 02 '23 03:03

steve_c


2 Answers

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.

like image 124
AnthonyWJones Avatar answered Mar 05 '23 17:03

AnthonyWJones


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.

like image 31
Alan Moore Avatar answered Mar 05 '23 16:03

Alan Moore