• 0

Regex c# remove white space but not inside <pre> and </pre>


Question

Hi all

 

I am trying to write some regex to remove all white space from html.

 

but the regex i am currently using doesn't factor in that in the pre tags there maybe opening "<" and closing ">" tags

 

This matches everything inside the pre tags

 

(<)\s*?(pre\b[^>]*?)(>)([\s\S]*?)(<)\s*(/\s*?pre\s*?)(>)

 

e.g.

(009)156 (010) (0)<pre> <test> edehofo<w<dieoj >  ></pre>     yuui u    ji 

will match 

<pre> <test> edehofo<w<dieoj >  ></pre>

 

and 

(?<=\s)\s+(?![^<>]*</pre>)

 

eg will almost work but does not work if there is an "<" or ">" in the mark up.

 

space[     ]spaces <pre>[          ]spaces</pre>space[      ]spaces 

 

will result in 

space[ ]spaces <pre>[ ]spaces</pre>space[ ]spaces 

 

but if there is a "<" or ">" in the pre tags then it will not work.

 

Could anyone help me

 

 

 

 

 

 

 

 

 

 

10 answers to this question

Recommended Posts

  • 0

A warning: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags

 

A solution: http://stackoverflow.com/questions/8762993/remove-white-space-from-entire-html-but-inside-pre-with-regular-expressions (same as your regex)

 

Just be careful with regex and HTML, parsing it to a C# object and then outputting it without whitespace is probably a better way to do this (likely to be slower though).

 

You shouldn't include < or > in <pre>, they should be escaped to &lt; and &gt;

  • 0

Thanks, but I've already been to those sites and a lot of others trying to find an solution.

 

From that its highlighted that I maybe able to do it in to step then...

 

1. encode all html with in pre tags

2. then use (?<=\s)\s+(?![^<>]*</pre>) to remove white space.

 

I am finding it hard to now find regex which will encode html with in a pre tag.

I love cats and dogs but dogs > than cats

<spaces>       <spaces>
<pre>
    1 > 0  = ?

    <code>       dedw</code>
</pre>

should be 

I love cats and dogs but > than cats <spaces> <spaces>
<pre>
    1  &gt; 0 = ?
    &glt;code&gt;       dedw &gt;/code &gt;
</pre>

It would be easier if i had some regex which basically ignored everything between a given tag.

 

I am doing my own research and trying to find the answer... but thought i would clarify what I am trying to do.

 

Thanks if you can help me find a solution

  • 0

Hi Eric

 

I'm trying to do it for c#

 

Basically I can get what i want if I can strip out white-space but not between two sets of chars

 

e.g.  <pre> anything </pre> or <code> anything </code>

 

seems more challenging that i thought it would be.

 

 (?<=\s)\s+(?![^<>]*</pre>)  is awesome but if i could get it to basically ignore everything inside of a given tag

 

My understanding of how to get the right syntax for regex is limited.

 

Match everything but not between tag(pre or code) and remove white space.

 

any help with getting this to work would be so awesome.

  • 0

How about the following: http://snipd.net/parsing-xhtml-into-a-dom-tree-in-c

You avoid using regex as you simply parse then print the HTML instead.

 

 

You might also want to re-read my first link, which points out that you cannot parse arbitrary (X)HTML using a regex. It is not possible as regex is not powerful enough to parse (X)HTML. (Parsing a limited subset is possible)

  • 0

to anyone who is good with regex please help

 

(?<=\s)\s+(?![^[<p]+?[e>])

 

cant not get this to work but must be close?

 

to: Lant

 

Sorry but i don't need to parse the HTML... i am not trying to validate it or read it really... 

 

I am wanting to remove white space but only when outside of a given tag like say <pre> or <code>

 

It has been working fine with (?<=\s)\s+(?![^<>]*</pre>)  until i hit a new requirement which.... is that the <pre> tag can contain < or >

 

which this regex does not support. One suggestion was to replace < and > with their HTML versions &lt; and &gt;

 

but again i would need to have something which only applied this on html with in tag the <pre> tag and I would need to do it in c#

 

seems easier to just get the regex to ignore things between tags some how...

 

Thanks

  • 0

If you don't mind doing the replace in C#, you can use capture groups with this pattern.

(?:\<pre\>)(.*)(?:\<\/pre\>)

It should capture everything between the pre tags and the value of the capture can then be string.Replaced on. I am working on a Regex replace version so you can use RegexOptions.Compiled. This regex was tested with CaseInsensitive and SingleLine (despite it being multi-line, using that to adjust how it handles .*)

 

1cKDh7e.png

 

 

so for example:

 

private static Regex preBlockMatch = new Regex(@"(?:\<pre\>)(.*)(?:\<\/pre\>)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase);

 

(code block)

string newValue = preBlockMatch.Captures[0].Value.Replace("<", "&lt;");

(code block)

 

obviously room for some enhancement but it gets you started

  • 0

Thought I would share what I got working......

 

Also thanks!!! to Squirrelington for the regex for the between stuff

 public class MinifiedStream : MemoryStream
        {
            private readonly Stream _output;
            public MinifiedStream(Stream stream)
            {
                _output = stream;
            }

            private static readonly Regex Whitespace = new Regex(@"(?<=\s)\s+(?![^<pre>]*</pre>)",RegexOptions.Compiled);

            private static readonly Regex PreBlockMatch = new Regex(@"(?:\<pre\>)(.*)(?:\<\/pre\>)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase);

            Dictionary<string, string> result = new Dictionary<string, string>();

            public override void Write(byte[] buffer, int offset, int count)
            {
                var html = Encoding.UTF8.GetString(buffer);

                //------------------------------------
                var matches = PreBlockMatch.Matches(html);
                int loopcount = 1;
                foreach (Match match in matches)
                {
                    var token = Guid.NewGuid().ToString() + "_"+ loopcount;
                    html = html.Replace(match.Value, token);
                    result.Add(token, match.Value);
                    loopcount ++;
                }
                //------------------------------------



                html = Whitespace.Replace(html, string.Empty);
                html = html.Trim();

                //-----------------------------------
                foreach (var match in result)
                {
                    html = html.Replace(match.Key, match.Value);
                }

                //-----------------------------------

                _output.Write(Encoding.UTF8.GetBytes(html), offset, Encoding.UTF8.GetByteCount(html));
            }
        }

But still feels as if you should be able to create a straight regex version.

 

if anyone can help me improve that would be awesome

  • 0

I agree that there should be a way to get it exclusively in regex but I am only really good at matching things, I don't have a lot of experience in replacement syntax. I know you can do $1 for the first group, $2 for 2nd or ${name} for named groups but how to modify the contents of those groups in the replacement is beyond me atm. Maybe someone with more experience will be able to chime in. :) Glad it is working thus far though. \o/

 

btw the regex I gave you, I probably went a little too crazy with the non-capture groups. I think at the time I was trying some funky magic to try and capture parts of it for replacement purposes but ended up with that.

<pre>(.*)</pre>

would probably be fine as well. lol

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Nice! My $100 refurbished iPad 8 that I bought last year for a small project (and still runs like new cuz it's been mostly in storage the past several months) will get this v26 upgrade. I'm definitely gonna scope out OS26 on this device before upgrading my also-supported refurbished iPhone SE 3rd Gen (only got it for the 5G UW support).
    • Hello, The separate discussion about VLC has been moved to its own thread at  Regards, Aryeh Goretsky  
    • Hello, I am guessing this is the result of using a third-party tweaking tool instead of changing things within Windows settings. Windows 11 has a decent set of configuration options for the display, but they tend to be scattered throughout the operating system due to fragmentation of product ownership/inconsistent standards being applied by Microsoft. There are a few places in Windows 11 where you can modify the various display settings in order to get them to your liking: Under Settings → System → Display you can stroll down to the Scale & layout section and change the Scale and Display resolution settings to whatever you prefer.  For the Scale option, you can click on the text box to choose between the various pre-populated settings.  If none of those are exactly what you are looking for, click on the caret ("") caret to open the Custom scaling setting (also available under Settings → Display → Custom scaling).  I would recommend this as an option of last resort as this can cause display issues in various programs. I strongly recommend using the screen's native Display resolution here; it should show up as the "(Recommended)" resolution.  If it does not, you may need to install your monitor's profile information file (basically, a device driver for your monitor) to get the correct setting. Another place to look at making changes to fonts is under Accessiblity → Text size.  There is a slider bar for changing the text size from 100% to 225% there. You can try making changes to the ClearType settings.  It's a little bit finer-grained than the others, but it may make the text easier to view on the display.  Run the ClearType Text Tuner (filename: CTTUNE.EXE) and go through the wizard. You may want to do this several times under different lighting conditions or times of the day to figure out what works best for you overall. Lastly, you may want to look into using a dedicated assistive screen technology program from a third-party.  Microsoft provides a Screen Magnifier and a Narrator for text-to-speech, but they provide only basic functionality, and you may find that a third-party program works a lot better.  The pros of this is that third-party assistive technology programs tend to work quite well under Windows; Microsoft has historically worked closely with third-party developers of assistive technologies.  The cons of this are that such tools tend to be on the expensive side, since they are often sold to schools, businesses, or paid for by insurance companies, not individuals. Regards, Aryeh Goretsky  
    • Totally agree with you. I think people, especially on tech sites, need to realize that they’re the minority. Microsoft isn’t going to waste time on things that, in the big picture, don’t matter to the majority.
    • I think a lot of people here are too young to even remember Aqua.
  • Recent Achievements

    • Dedicated
      MadMung0 earned a badge
      Dedicated
    • Rookie
      CHUNWEI went up a rank
      Rookie
    • Enthusiast
      the420kid went up a rank
      Enthusiast
    • Conversation Starter
      NeoToad777 earned a badge
      Conversation Starter
    • Week One Done
      VicByrd earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      506
    2. 2
      ATLien_0
      267
    3. 3
      +FloatingFatMan
      257
    4. 4
      Edouard
      203
    5. 5
      snowy owl
      178
  • Tell a friend

    Love Neowin? Tell a friend!