HTML Stripper

Free online HTML tag remover. Quickly strip HTML tags and get clean plain text. Optionally keep specific tags (br, p, b, i, a). All processing happens locally in your browser.

Keep these tags:

HTML to Plain Text: It Is Normalization, Not Just Deleting Tags

Many tutorials describe "stripping HTML" as "delete everything between < and > with a regex" and call it done. But a strict HTML-to-plain-text conversion is a normalization pipeline that must at least do four things: decode character entities, collapse runs of whitespace, insert line breaks for block-level elements, and discard scripts and styles. If you only delete tags while ignoring entities and whitespace, what you get is not "clean text" — it is a half-stripped blob carrying &nbsp;, &amp; leftovers and odd indentation. This tool takes the lightweight regex route (it runs entirely in your browser and uploads nothing), which is great for quick cleanup; but you should know exactly where its boundary lies so you can judge whether the output is trustworthy.

On sourcing: HTML is an international standard defined by the W3C and the WHATWG HTML Living Standard. The entity table and the whitespace rules both come from that specification. One cross-locale gotcha worth flagging: the HTML non-breaking space &nbsp; (U+00A0) is not the same character as the CJK full-width space (U+3000) that appears in Chinese text. The tool treats both as ordinary characters and does not collapse them, so a Chinese page stripped here can show "spaces that will not go away" — that is expected, not a bug.

Table 1: HTML Entity Decoding Rules

A conforming HTML parser resolves character references into their Unicode code points at parse time. The WHATWG HTML Living Standard named-character-reference table holds 2,231 named references (HTML 4.01 defined only 252), plus two numeric forms — decimal &#nnn; and hexadecimal &#xNNN; — that can represent any Unicode code point. The most common ones and their real code points:

ReferenceDecodes toUnicodeCategory / use
&amp;&U+0026syntax char (must escape)
&lt;<U+003Csyntax char (tag start)
&gt;>U+003Esyntax char (tag end)
&quot;"U+0022attribute quote
&apos;'U+0027apostrophe (added in HTML5)
&nbsp;no-break spaceU+00A0typographic space (not collapsed)
&mdash;—U+2014em dash
&copy;©U+00A9copyright sign
&pound;£U+00A3currency sign
&yen;¥U+00A5currency sign
&#8212;—U+2014numeric reference (equals &mdash;)

Note: this tool is a pure regex stripper and does not decode entities. So &nbsp; stays in the output as the literal text &nbsp; rather than becoming a space. To truly decode, use a browser DOM parser or a backend library. Example 3 below shows this directly.

Table 2: Block-Level Element Line-Break Rules

Plain text has no "tags", but humans expect "paragraphs". During rendering, different block-level elements should inject different numbers of line breaks when textified. The most-asked rules:

ElementAdds break?WhereNote
<p>yes1 line before & afterparagraph; common segmentation base
<div>yes (visually)1 line before & afterblock container; add break when textifying
<br>yes1 line after onlyhard break; no closing tag
<li>yes1 line before each itemlist item; usually prefix "· " or "1. "
<tr>yes1 line after each rowtable row; column alignment in Table 5
<h1>–<h6>yes1 line before & afterheading; often blank line for emphasis
<blockquote>yes1 line before & afterquote block; prefix ">"
<hr>no (semantic)use "---" insteadhorizontal rule; no plain-text equivalent

By default this tool does not add these breaks — it only deletes tags, so the default output paragraphs get "glued" together. To keep a sense of paragraphs, check "keep" for <p> or <br> (see Example 2).

Table 3: Elements to Discard vs Attributes to Keep

Element / attributeHandlingReason
<script>drop entirelyexecutable code; plain text neither needs nor should keep it
<style>drop entirelyCSS; unrelated to content
<!-- comment -->drop entirelyauthor note; invisible to readers
<noscript>drop entirelyno-script fallback; meaningless once textified
alt (img)keep as textalternative text; the only readable info for an invisible image
title (element)keep as texthover hint; can fold into body or a bracket note
<img> itselfdrop tagimage cannot render as plain text, but alt should be textified

This is where "drop formatting, keep content" lands: <script>/<style>/comments are removed, while semantic-bearing attributes like alt and title are restored to readable words.

Table 4: Whitespace Collapsing Rules (HTML white-space collapsing)

The HTML specification says that under default rendering, a run of whitespace characters (spaces, tabs, newlines) is collapsed to a single space, whitespace at element boundaries is collapsed, and leading/trailing whitespace on a line is removed. Common cases:

CaseSpec behaviorPlain-text tip
runs of space / tab / newlinemerge to one spacereplace \s+ with single space
whitespace at tag boundarycollapsedclear it after tag removal
leading / trailing whitespaceremovedtrim() each line
&nbsp; (U+00A0)not collapsedkeep, or replace with normal space as needed
CJK full-width space (U+3000)treated as a characterkeep or convert per locale

Note: collapsing applies only to ordinary whitespace. &nbsp; and the full-width space (U+3000) are excluded — which is exactly why you sometimes see "spaces that will not delete" after stripping.

Table 5: <table> to Plain Text Alignment Problem

Turning a table into plain text is hard not because of "removing tags" but because of "aligning columns". Plain text has no cell width, so these issues make output unreadable:

ProblemSymptomTip
column alignmentcells vary in length; lines misalignfixed-width pad or Markdown table
colspanone cell spans many columns; width math gets complexmerge and label
rowspancontent spans rows verticallyrepeat or leave blank per row
nested tablestable inside tableflatten inner first, then outer
empty cellsmissing content shifts layoutpad with placeholder (e.g. "-")

Verdict: if your goal is a "readable table", plain-text stripping is the wrong tool — hand it to a structure-preserving tool like Markdown Preview. Use this tool only when the goal is "format-free plain text".

Table 6: HTML Stripping vs Markdown Conversion

DimensionPlain-text strip (this tool)Markdown conversion
structurediscardedkeeps headings / lists / quotes
linksanchor text onlykeeps [text](URL)
headingsplain line# prefix
listsplain line- / 1. prefix
bold / italiclostkeeps ** / *
tablesmisaligned (see above)keeps pipe table

In short: use this tool for "plain text", use Markdown Preview for "lightweight formatting". They are not substitutes; they serve different goals.

Three Worked Examples (using the page default input)

All three examples use the default HTML already in the tool's text box, so they match exactly what you see when you open the page. Output was verified character by character with a script.

Example 1: Strip all tags (no keep boxes checked)

The default input is 186 characters and contains 18 tags. After stripping all, the result is 88 characters:

Welcome to My Website
This is bold and italic text.

  Item 1
  Item 2

Learn more here.

Notice how the heading, paragraphs and list are "pressed" into continuous text, and the <li> leading spaces remain (no collapsing) — the typical product of "delete tags only".

Example 2: Keep <p> and <br>

With p and br kept, the output grows to 102 characters — the <p> tags are kept verbatim in the text:

Welcome to My Website
<p>This is bold and italic text.</p>

  Item 1
  Item 2

<p>Learn more here.</p>

Note: this tool's "keep" means keep the whole tag, not turn <p> into a line break. So what you see is the literal angled-bracket text <p>, not a real blank line. If you want paragraph breaks, post-process or switch to a structure-preserving tool.

Example 3: Entities are not decoded (key trap)

Input <p>Price: &pound;10 &amp; &copy; 2026&mdash;end&nbsp;space</p> yields 55 characters with entities kept literally:

Price: &pound;10 &amp; &copy; 2026&mdash;end&nbsp;space

A conforming parser would decode it to Price: £10 & © 2026—end space. The gap exists because entity decoding belongs to the HTML parse stage, which this tool does not perform. For clean output, decode entities first in another environment, or accept the literal residue and replace by hand.

Frequently Asked Questions

Why doesn't &nbsp; become a space after stripping?

Because this tool is a pure regex stripper that only deletes <...> tags and does not run HTML entity decoding. &nbsp; (U+00A0 no-break space) stays in the output as the literal text &nbsp;. To really turn it into a space, decode entities first with a browser DOM or a backend library, then strip tags.

After keeping <p>, why is the <p> text still in the result?

The keep logic is "keep the whole tag", meaning the matched <p> tag is left in the text as-is, not replaced by a line break. It suits debugging where you want to see the tag still present; for real paragraph breaks, post-process or use a structure-preserving tool.

Why does a <table> turn misaligned in plain text?

Plain text has no cell width, so uneven column lengths, colspan/rowspan, nested tables and empty cells all cause misalignment. Plain-text stripping only solves "remove tags"; the alignment problem needs fixed-width padding or a pipe table in Markdown Preview.

Should I strip HTML or convert to Markdown?

The goal decides: for format-free plain text (word counts, storage, feeding a model) use this tool; for lightweight formatting that keeps headings, lists, links and tables, use Markdown Preview. See Table 6 above.

Why do spaces look wrong after stripping a Chinese page?

Chinese pages mix two spaces: HTML &nbsp; (U+00A0, Western no-break space) and the CJK full-width space (U+3000). They are different characters and neither is covered by whitespace collapsing, so both survive stripping. Treat them deliberately — keep or convert to a half-width space — rather than assuming they will vanish.

Want to analyze the cleaned text further? Count characters with Word Counter, or compare before-and-after with Text Diff. For more hands-on tips, see the HTML Stripper guide.