Skip to main content

Strip HTML Tags: How to Remove HTML and Get Clean Plain Text

A practical guide to stripping HTML tags down to plain text — removing markup, decoding entities like &, cutting script code, and handling whitespace.

Published By Li Lei
#html #plain-text #text-cleaning #web-content

Strip HTML Tags: How to Remove HTML and Get Clean Plain Text

Most of the text I want to reuse never arrives clean. I copy a paragraph out of a web page, an email, or a rich-text editor, and what lands on my clipboard is half words and half markup — <div>, <span>, inline styles, and a scattering of &amp; and &nbsp; that look like typos but are not. Stripping HTML tags is the step that turns that mess back into the words a human or a program can actually use. This guide walks through what stripping really does, where it goes wrong, and how to do it in one paste.

What "stripping HTML tags" actually means

The core idea is simple: stripping removes the <tags> and leaves the text content behind. <p>Hello</p> becomes Hello. That part is easy, and a one-line regex can do it.

The hard part is everything around the tags. Good stripping does three jobs that a naive remover skips:

  • It decodes HTML entities so that &amp; turns back into &, &#39; into an apostrophe, &lt; into <, and &nbsp; into a real space. Those sequences are how HTML escapes characters that would otherwise confuse the parser. They are not part of your text, and if you leave them in, they show up as literal gibberish wherever you paste next.
  • It collapses the extra whitespace that markup leaves behind. HTML source is full of indentation, newlines between tags, and blank lines that mean nothing to the reader. Remove the tags and you are left with ragged gaps. A clean strip folds those down so the output reads like prose, not like a column of holes.
  • It removes the code inside <script> and <style>, tag and contents together. This is the trap that catches most quick strippers, and it deserves its own section below.

So stripping is not just deletion. It is deletion plus decoding plus tidying. Get one of those wrong and the output still looks broken.

A worked example: from markup to clean text

Here is a snippet close to what you copy off a real page:

<h1>Spring Sale</h1>
<p>Save up to 40&#37; on tea &amp; coffee.</p>
<p>Use code&nbsp;<b>SPRING</b> before May&nbsp;31.</p>
<script>track('promo_view');</script>

Run it through a proper strip with block tags converted to line breaks, entities decoded, and script content removed, and you get:

Spring Sale
Save up to 40% on tea & coffee.
Use code SPRING before May 31.

Look at what happened. The <h1> and each <p> became their own line, so the structure survived instead of collapsing into one run-on sentence. &#37; decoded to %, &amp; to &, and the two &nbsp; to ordinary spaces. The <b> around SPRING vanished but the word stayed. And track('promo_view') — the JavaScript that a careless tool would have dumped straight into your text — is simply gone. That is the difference between text you can paste and text you have to clean again by hand.

Why script and style content is the real test

Plain tag removal works like this: find anything between < and > and delete it. Feed it <script>alert(1)</script> and it deletes <script> and </script> — but the alert(1) in the middle is not inside angle brackets, so it survives. You end up with the function body sitting in your output like a stray line of code. The same happens with <style> blocks, where a wall of CSS leaks through.

The fix is to cut the entire <script>...</script> and <style>...</style> blocks first, contents included, and only then strip the remaining tags. Order matters. When you pick a tool, paste a snippet that contains a script tag and check the output. If you see JavaScript or CSS in the result, the tool is stripping in the wrong order, and any page you process will carry that noise. The strip HTML tags tool cuts those blocks out by default, so this never surprises you.

Keeping line breaks versus joining one line

There are two outputs you might want, and they are opposites.

For reading — an email you are reviewing, a page body you are quoting — you want line breaks preserved. Tags that end a block (p, div, li, h1 through h6, br, tr) should each become a newline, so the result reads with the same paragraph rhythm as the original. A heading followed by two paragraphs should land as three lines, not one.

For feeding another program — a search index, a tokenizer, a script that splits on its own delimiter — you often want everything joined into a single continuous line, no internal breaks to confuse the next step. A good stripper makes this a toggle rather than forcing one behavior. The mistake I see most often is running a whole HTML page with the line-break toggle off, then wondering why every heading and list item crushed into one unreadable string. Match the toggle to the job: on for reading, off for piping.

When you want text only — and when you don't

Stripping is the right move when formatting is baggage: full-text search, word counts, building a corpus to feed a model, or just pasting clean copy into a chat box or terminal where stray markup would break the layout. In all of those, structure like bold and links is dead weight, and you want it gone.

It is the wrong move when the formatting is the point. If you are moving content into notes or a blog and want to keep the bold, the headings, and the links as editable structure, you do not want plain text — you want a format conversion. That is a different job, and a converter that turns <b> into ** and <a> into [text](url) serves it better than a stripper that throws all of that away.

A note from my own workflow: I do this constantly when prepping documents for a count. Tagged content folds <p> and class names straight into the total, so the number is always inflated. I paste the HTML, strip it with entities collapsed to single characters, then run the clean text through the word counter. Only then do I trust the figure — by character for Chinese, by word for English — because there is no tag noise left to throw it off. It takes ten seconds and it has saved me from quoting wrong numbers more than once.

A short checklist before you paste

  • Turn on block tags to line breaks for anything you intend to read; turn it off only when a program will consume a single line.
  • Turn on decode entities so &amp;, &#39;, and &nbsp; come out as the real characters they stand for.
  • Confirm the tool removes script and style contents, not just the tag pair, or you will find code in your words.
  • Collapse extra blank lines if the source had loose spacing.
  • Remember the input stays local — nothing about stripping HTML needs a server, and a good tool runs entirely in your browser.

Strip the markup, decode the escapes, tidy the gaps, and what is left is what you actually wanted all along: the words, and nothing else.


Made by Toolora · Updated 2026-06-13