雜記 › 技術筆記 › 16 組開關實測 HTML 去標籤:報 19 個標籤,實際刪掉 148 個字元

16 組開關實測 HTML 去標籤:報 19 個標籤,實際刪掉 148 個字元

16 組開關實測 HTML 去標籤:同一串報 19 個標籤、實刪 148 個字元;保留內容一關,計數從 19 掉到 14,標籤名填 p 會連 pre 一起刪,頓號還不是分隔符。

三個數算的是三種帳

貼一段 HTML 跑完,統計那行只給三個數:移除標籤 19、原始字元 227、結果字元 79。可 19 和 148 不是同一種量。把這頁範本(150 行 / 6391 位元組)裡唯一的處理函式逐字抽出來在 Node 裡驅動,跑同一串 13 行 / 227 字元的樣例:19 是 6 處 .match() 命中數之和(第 92 行起),227 與 79 是第 146、147 行的兩個 .length,相減的 148 才是真正消失的字元數——每報 1 個標籤,就有 7.79 個字元走掉。

模式(去除所有 / 去除指定)× 保留標籤內內容 × 去註釋 × 壓空格,4 個開關展開成 16 組。在 HTML 標籤去除 上把這 16 格逐格撥一遍,同一串 227 字元的結果全在下表。

16 組矩陣:只有 1 個開關動計數

組模式內容註釋空格移除標籤實刪字元
1all開開開19148
2all開開關19140
3all開關開19136
4all開關關19129
5all關開開14181
6all關開關14172
7all關關開14169
8all關關關14161
9指定開開開1086
10指定開開關1080
11指定開關開1074
12指定開關關1069
13指定關開開5133
14指定關開關5126
15指定關關開5121
16指定關關關5115

第 9 到 16 組填的是同一串 4 個標籤名。四個開關裡只有保留內容會動計數:移除標籤在四個區段恆為 19、14、10、5,註釋與空格一個都不影響它,結果字元只隨這兩個開關變。保留內容一撥,報數從 19 掉到 14、實刪反而從 148 漲到 181。

同一串 227 字元:柱高是實刪字元,柱頂是報出的標籤數 報 19 148 all 留內容 報 14 181 all 不留 報 10 86 指定 留 報 5 133 指定 不留

圖 1:四個區段各取註釋與空格都開的那一格。

保留內容一關,被刪的標籤不上數

all 模式關掉這一檔會換一條路徑:第 96 行那 6 個 blockTags 先被第 98 行的整塊正則刪掉,第 102 行才開始計數,所以塊的開閉標籤一個都不進「移除標籤」。樣例上 19 掉到 14,差的 5 個正是 <style>、</style>、<script>、</script> 和字串字面量裡的 <div>。

54 個字元的一串:<style>.a{}</style><script>var a="<div>";</script>text。保留內容開著是移除 5、輸出 17 字元;關掉只剩 4 字元的 text,移除標籤卻寫 0。

指定標籤做的是前綴匹配

標籤名填進去後,第 115 行拼出的正則 '<'+tag+'[^>]*>' 前面沒有邊界。填 p,作用在 40 個字元的 <p>段落</p><pre> 程式碼</pre><param name="x"> 上:移除標籤 4、輸出 12 字元,<pre> 與 <param name="x"> 一起被刪,closeRe 卻要求 </p\s*>,閉標籤留成殘渣——刪掉的 28 個字元只報了 4。填 i,69 個字元刪到 10,img、iframe、input 三個開標籤全沒。

分隔符少一種,整串一字未改

欄位標籤寫的是逗號分隔,清單兩處示範卻是頓號。第 109 行 split(/[,,\s]+/) 只認半形逗號、全形逗號和空白,頓號不在名單裡:照文案輸入 script、style 只切出 1 個 token、淨化成 scriptstyle,移除 0,84 個字元一字未改;同一串寫成 script,style,div 就是移除 6、刪掉 43 個。空值更安靜:28 字元的一串移除 0、輸出 16 字元,而同一串在 all 模式是移除 2、輸出 5 字元——移除 0 不等於輸出等於輸入。

「所有」這個詞撐不住

通用正則要求 < 後緊跟 ASCII 字母且必須有閉合的 >,預設組合有 7 類標記原樣留下:<!DOCTYPE html> 的 15 個字元、<?xml version="1.0"?> 的 21、<3.5 的 4、<> 的 2、</> 的 3、未閉合 <div 的 4、< b>x</ b> 的 10。實體形態也不還原:&lt;div&gt; 的 11 個字元 0 匹配、一路留到輸出,&nbsp; 與 U+00A0 同樣不在處理範圍;比較運算子也會被當成標籤,<b && c> 這 8 個字元就是被吞掉的那個。

註釋與空格這兩檔

註釋是第 85 行的非貪婪匹配,遇到第一個結束符就收:未閉合的 17 字元原樣保留,巢狀的只吃掉 19、留 6 個字元殘渣。

空格是第 136 行裡的 3 個 .replace(),壓成 1 個空格而不是刪除:中文段 9 個字元變 7;全形空格 U+3000 的 9 變 8,只刪行首那 1 個;U+00A0 的 4 個不變、U+200B 的 3 個不變;單獨換行不合併,3 連換行才從 5 變 3;CRLF 從 6 變 4。程式碼縮排最受傷:<pre> 段剝掉標籤是 25 字元,開了壓縮剩 19,首行縮排被直接刪光。

一整頁網頁跑下來

換一頁 19 行 / 569 字元的真實結構:預設組合報 32 個標籤、輸出 277 字元,第一行仍是 <!DOCTYPE html>,其中漢字只有 52 個、程式碼符號 53 個。只關保留內容,報數變 26、輸出 88 字元,兩版差的 189 個字元正是 CSS / JS / JSON-LD 原始碼的體量。

沒有批次入口,也沒有第二遍的驚喜

「批量」在這頁不存在:第 70 行只讀 1 個輸入框的值、第 44 行只有 1 個輸出區,0 處檔案入口、0 處 FileReader、0 處遍歷迴圈,跑第二段只能手工全選替換;6 個呼叫點無節流,5000 字元每敲一個字都重跑 12 次 .replace()。把輸出灌回去跑第二遍,11 組裡 10 組逐位元組不變,只有 <<b>hi> 繼續被改:第一遍輸出 4 字元的 <hi>,第二遍輸出 0 字元,而第二遍的移除標籤普遍顯示 0——它是本次快照、不是進度。

22 條文案對照

把 config/tools.php 第 1144–1152 行的 22 條文案逐條對著實測判一遍:[一致] 7 條、[衝突] 15 條,衝突集中在 「提取纯文本」、「仅移除指定标签」、「可选去除连续空格和换行」 這三句。站內那篇講去除 HTML 標籤的舊文是經驗向敘述,這篇不重複它,只把開關矩陣與計數補齊。

常見問題

Q:報 19 個標籤,就是刪掉 19 個標籤嗎?

不是。同一串 227 字元,保留內容開著報 19、關掉報 14,實刪字元反而從 148 漲到 181:整塊刪除先跑、計數後跑,比值從 7.79 跳到 12.93。

Q:只填 p,為什麼連 <pre> 一起沒了?

第 115 行的正則沒有前綴邊界,p 會命中 pre 與 param;閉標籤那邊又要求一字不差,於是開標籤被刪、閉標籤留成殘渣。

Q:結果裡還留著實體形態怎麼辦?

這頁 0 處實體解碼、0 處 DOM 解析,全是字串替換:&lt; 這種形態會一路留到輸出。

📎 相關文章

SVG 轉 PNG 後外部引用的圖丟了一半:同一份 594 B 檔案預覽有 3 張圖、成品只剩 1 張 2026-10-30 二進位轉 Base64 這一頁:前綴只有 5 檔,換行能解、連字號和底線直接報錯 2026-10-30 替應用做商店介紹圖,點匯出卻拿到 1242×2688:8 檔畫布預設的像素帳、噪點 24.83 倍體積與預設被裁掉 134.93 px 的手機框 2026-10-30 16 個鍵進、4 個欄出:JSON 轉表格的表頭聯集、點號展平與 CSV 引號規則 2026-10-30 取消勾選「保留註解」後,format-js 把 24 字元 URL 壓成 13 字元殘缺碼 2026-10-30