删除线文本生成器

为每个字符尾部叠加 Unicode 组合字符 U+0336(双删除线再叠一个 U+0337),生成可粘贴到任何输入框的纯文本删除线,并用码点、码元、字素三个口径和实测渲染宽度证明它真的加上了。

原文字素9
输出码点18
输出码元18
组合标记数9
UTF-8 字节45
渲染宽度实测零宽(与原文同宽)
原样渲染预览:柳̶泉̶工̶具̶删̶除̶线̶示̶例̶

输入框里按 Ctrl / Cmd + Enter 生成(Enter 单独按是换行,多行文本必须留给它);点「生成删除线」同样触发。「渲染宽度实测」用 measureText 比较加标记前后的字符串宽度:两者相等说明标记是零宽叠加、真的合进了字素;宽度变大说明当前字体把它画成了独立字符,粘贴到部分平台会散开。

使用方法

  1. 在待处理文本框里填要加删除线的内容,默认已经是示例值 柳泉工具删除线示例(9 个字素)。允许 1~5000 字,换行会被保留,每一行都单独处理。
  2. 选删除线样式:默认「单删除线」= 每个字符后面追加 U+0336(COMBINING LONG STROKE OVERLAY);「双删除线」= 再追加一个 U+0337(COMBINING SHORT SOLIDUS OVERLAY);「斜线叠加」= 换成 U+0338。
  3. 按 Ctrl/Cmd + Enter 或点「生成删除线」。结果区立刻给出可粘贴的纯文本,同时刷新 6 个指标。
  4. 看渲染宽度实测这一格:显示「零宽(与原文同宽)」说明叠加上成功;显示具体变宽了多少像素,说明当前字体没把组合标记合进字素,需要换字体或改用 Markdown 写法。
  5. 点「复制结果」把纯文本带走;点「载入示例」把输入框还原成 柳泉工具删除线示例 并重算。

这个删除线文本生成器能解决什么问题

一是在没有富文本的地方划掉字。电商后台的商品名、内部系统的备注、群接龙的自填项,这些输入框都不认 <s> 标签也不认 Markdown,只有纯文本能进去。删除线的本质是把「横线」也当成一个不可见的字符塞进字符串里,它跟着内容一起被复制、被粘贴、被存库,不需要目标端做任何渲染支持。

二是把「改过了」这件事写进文本本身。改价记录写 原价 99 不如写划掉的原价,表格里一眼就知道哪个是失效项。删除线文本生成器输出的字符串在数据库中仍然是完整的字符序列,字段类型不用改,索引长度会变长这一点需要预留。

三是核对到底有没有加上。很多人粘出去发现别人看到的还是干净文字,就以为工具坏了。其实字符串里的码点数已经翻倍,只是对方字体缺这个组合字形没画出来。这一页同时给出码点、码元、字素三个数字和实测宽度,能直接区分「没加上」和「加上了但对方没渲染」这两种完全不同的情况。

四是给不同平台挑合适写法。同一句「已下线」,Unicode 组合删除线是 6 个码点的纯文本,Markdown 的 ~~已下线~~ 是 7 个字符、需要目标端支持 Markdown,HTML 的 <del> 是 14 个字符、只在 HTML 环境生效。选哪种取决于内容最终落在哪里,本页只产出第一种。

这个删除线文本生成器不做加粗、斜体、上标小号字,那些是另几种组合字符的活,用「特殊字体生成器」;也不做下划线,那是 U+0332 的低线叠加,用「下划线文本生成器」;更不做文本统计,字数与字符数的口径用「字数统计工具」和「字符数统计工具」分别看。

原理与规则说明:U+0336 叠加、三口径计数与渲染依赖

算法本身只有一行:把字符串拆成码点,每个码点后面拼上组合标记。代码是 Array.from(s).map(function (c) { return c + STRIKE; }).join(''),其中 STRIKE 是 '\u0336'。用 Array.from 而不是 s.split('') 是因为后者按 UTF-16 码元切分,会把表情符号这类代理对拆成两个半字符,组合标记插在半个字符中间,输出直接损坏。

参数为什么是这两个码位。U+0336 COMBINING LONG STROKE OVERLAY(十进制 822)是贯穿整个字身的横线叠加标记,这是浏览器与系统字体支持最广的删除线组合字符,聊天软件、Excel、Word 里普遍能画出来。U+0337 COMBINING SHORT SOLIDUS OVERLAY(十进制 823)严格说是一条短斜杠叠加,单独用只会在字身上留下一道斜线;和 U+0336 叠在同一个基字符上才形成「横线加斜线」的双线错觉,所以本页把双删除线定义为这两个标记连用,而不是把某一个标记重复两遍——同一码位重复两次只会完全重合,渲染出来仍然是一条线。

组合标记必须紧跟基字符,顺序不能颠倒。正确写法是 基字符 + 组合标记,例如 删 后面跟 U+0336;反过来把 U+0336 放在最前面,它就找不到可叠加的基字符,浏览器要么画成一个独立的空白占位,要么直接丢弃,整串文本看起来毫无变化但码点已经变了。这也是本页输出永远以真实字符开头的原因。

三个口径分别回答三个问题。码点(Array.from(s).length)回答「字符串里到底有没有标记」;码元(s.length)回答「数据库字段和 varchar 长度会涨到多少」;字素(Intl.Segmenter 的 grapheme 粒度,或用「非 Mn 类码点计数」等价实现)回答「人眼看到几个字」。示例串 柳泉工具删除线示例 加单删除线后是 18 个码点、18 个码元、9 个字素、9 个组合标记,UTF-8 字节从 27 涨到 45。宽度没变而码点翻倍,就是这个工具生效的标准状态。

为什么用实测渲染宽度判断生效,而不是靠肉眼。组合标记属于 Mn 类,按 Unicode 规则不占前进宽度(advance width),所以 measureText(加标记后的串).width 与 measureText(原串).width 相等才是正常结果——这一条能反过来证明标记是「叠加」而不是「插入了一个独立字符」。如果宽度明显变大,说明当前字体没有对应的叠加字形,浏览器用了备用字形的独立占位,这种情况下粘贴到别的平台会散成乱码,应当改用 <del> 这类富文本写法。肉眼看不看得见不作为判据,因为字体、字号、缩放都会影响观感。

叠加顺序与组合类决定渲染上限。Unicode 规定 Mn 类标记按规范性组合类(Canonical Combining Class)排序,性质相同的标记之间保持书写顺序。U+0336 与 U+0337 属于同一类叠加标记,写 U+0336 U+0337 与写 U+0337 U+0336 在多数渲染引擎里结果一致,但为了跨平台输出稳定,本页固定按「先长横线、后短斜线、再长斜线」的顺序拼接,不做随机排序。

完整示例(数值仅作演示)

示例条件与页面打开时的默认值完全一致:待处理文本 = 柳泉工具删除线示例(9 个字素),样式 = 单删除线(U+0336)。实测结果如下:

下面是默认示例的真实输出,可以直接复制出去对照:

柳̶泉̶工̶具̶删̶除̶线̶示̶例̶

同一个输入换成常见内容时,长度按「单删除线 = 字素 × 2、双删除线 = 字素 × 3」线性放大,下表前 12 行默认显示,点「加载更多」展开剩余 4 行:

输入示例字素数单删除线码点双删除线码点UTF-8 字节(单)粘贴备注
已下线36915常规可用
删除线36915常规可用
作废24610常规可用
A1235单字母也会被叠加
OK2468拉丁字母覆盖良好
2026481214数字同样可用
v2.0481214点号也会被叠加
旧价 995101517空格被叠加时线会断开
柳泉工具481220汉字各占 3 字节
限时优惠481220常规可用
暂不可用481220常规可用
已售罄36915常规可用

输入范围与对照表

输入框与样式选择项的范围、超限动作如下,右列是填错时结果区会显示的具体提示:

字段/情况允许范围超限或填错时的动作
待处理文本1~5000 个字素,必填空文本拒绝计算并提示「不能为空」;超过 5000 字素拒绝并报出实际字数
组合字符样式single / double / slash 三选一下拉框只能选预设项;值异常时回落到单删除线并提示
纯空白输入不视为有效内容只有空格或换行时拒绝,提示「只有空白,没有可加删除线的字符」
单独的组合标记不单独处理输入里已有孤立 U+0336 时保留原样,不重复叠加
表情与代理对按码点处理,不按码元切不报错;输出会把标记放在整个表情之后
换行保留按行拆分处理,\n 本身不加标记
超长文本上限 5000 字素拒绝;双删除线时输出可达 15000 码点,再放大就影响交互

三种写法的选择对照(同样是「已下线」这三个字):

写法字符长度生效条件适用位置
Unicode 组合删除线6 个码点纯文本,任何输入框聊天、昵称、表格单元格、数据库字段
Markdown ~~删除线~~7 个字符目标端支持 Markdown 语法README、Issues、支持 Markdown 的评论框
HTML <s>10 个字符内容会被当 HTML 渲染网页正文,语义是「不再准确」
HTML <del>14 个字符内容会被当 HTML 渲染修订稿,语义是「从文档中删除」

边界与渲染依赖说明

常见问题

为什么我粘贴出去看到的是干净文字,删除线不见了?

先看结果区的「输出码点」是不是原文的 2 倍(双删除线是 3 倍)。如果是,说明字符确实加上了,只是对方那一端的字体没有画出叠加字形。这种情况换字体、换应用就能显示;若码点没变,才是没生成成功,请点「生成删除线」重试。判断依据始终看码点,不要只看肉眼。

单删除线和双删除线到底差在哪,为什么双的要两个码位?

单删除线在每个基字符后加一个 U+0336(长横线叠加)。双删除线再加一个 U+0337(短斜线叠加),两个标记叠在同一个基字符上,视觉上像横线加了一道斜杠,显得更「重」。如果把同一个 U+0336 写两遍,两个标记完全重合,画出来还是一条线,所以双删除线必须用两个不同码位。

加完删除线后,字数统计怎么变了?

看你用哪种口径统计。按字素数没变(示例仍是 9),因为组合标记不单独成字;按码点或码元数则翻倍到 18,双删除线到 27。很多平台的字数统计按码元算,所以加了删除线的文案在按字数计费的场景(短信、广告投放)会多算一倍,这一点务必先核对。需要看纯字素口径请用「字数统计工具」。

为什么输入框里按 Enter 是换行,不是生成?

因为这里处理的是多行文本,Enter 必须留给换行——若照搬单行输入框的写法,用户就没法输入第二行了。所以本页用 Ctrl/Cmd + Enter 触发生成,鼠标点「生成删除线」也一样。页面上单行输入类的工具才用裸 Enter。

数据库存得下吗,字段要改吗?

字段类型不用改,但长度要预留。varchar(n) 的 n 通常按字符计,加单删除线后占用约 2 倍字符数,双删除线约 3 倍。示例 柳泉工具删除线示例 原文 9 个字符,单删除线后是 18 个,双删除线后是 27 个。若字段刚好卡在长度上限,改价格、状态这类短字段时建议把上限乘以 3 再留一点余量。

和 Markdown 的 ~~、HTML 的 <s> 该选哪个?

看内容落在哪里。目标是纯文本环境(聊天框、昵称、表格单元格、系统备注)就用本页的组合字符;目标是支持 Markdown 的编辑器(README、Issue)直接写 ~~文本~~ 更干净,长度也更短;目标是网页正文并且需要屏幕阅读器正确处理,用 <del>(表示从文档中删除)或 <s>(表示内容不再准确)——它们附带语义,但这正是纯文本做不到的部分。

组合字符会影响搜索和排序吗?

会。数据库按 UTF-8 字节比较时,已下线 与加标记后的字符串不是同一个值,等值查询、唯一索引、去重都会把它们当成两条不同记录。做文本匹配前应当先剥离 Mn 类组合标记,或者把「显示用的带标记文本」和「检索用的干净文本」分成两个字段存。

为什么工具不帮我把删除线去掉?

因为「去掉」有两种含义:只删掉删除线标记、保留原文,还是把划掉的内容整段丢弃。前者是清洗,后者是内容决策,混在一起做会误删数据。本页只负责生成;需要清理组合字符时,把文本粘到本页看码点数变化来人工核对,再决定如处理。

相关工具