From 480666e3f043f7ae11d5e9ca8c9154181a3ed93f Mon Sep 17 00:00:00 2001 From: Karlatemp Date: Sat, 28 Nov 2020 21:28:43 +0800 Subject: [PATCH] Improve String.dropAnsi() --- .../src/util/AnsiMessageBuilder.kt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/backend/mirai-console/src/util/AnsiMessageBuilder.kt b/backend/mirai-console/src/util/AnsiMessageBuilder.kt index dfa9082be..f33e83267 100644 --- a/backend/mirai-console/src/util/AnsiMessageBuilder.kt +++ b/backend/mirai-console/src/util/AnsiMessageBuilder.kt @@ -98,13 +98,28 @@ public open class AnsiMessageBuilder public constructor( // // @see https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#CSI%E5%BA%8F%E5%88%97 @Suppress("RegExpRedundantEscape") - private val DROP_ANSI_PATTERN = """\u001b\[([\u0030-\u003F])*?([\u0020-\u002F])*?[\u0040-\u007E]""".toRegex() + private val DROP_CSI_PATTERN = """\u001b\[([\u0030-\u003F])*?([\u0020-\u002F])*?[\u0040-\u007E]""".toRegex() + + // 序列具有不同的长度。所有序列都以ASCII字符ESC(27 / 十六进制 0x1B)开头, + // 第二个字节则是0x40–0x5F(ASCII @A–Z[\]^_)范围内的字符。[12]:5.3.a + // + // 标准规定,在8位环境中,这两个字节的序列可以合并为0x80-0x9F范围内的单个字节(详情请参阅C1控制字符集)。 + // 但是,在现代设备上,这些代码通常用于其他目的,例如UTF-8的一部分或CP-1252字符,因此并不使用这种合并的方式。 + // + // 除ESC之外的其他C0代码(通常是BEL,BS,CR,LF,FF,TAB,VT,SO和SI)在输出时也可能会产生与某些控制序列相似或相同的效果。 + // + // @see https://zh.wikipedia.org/wiki/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97#%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97 + // + // 注: 缺少详细资料, 只能认定 ansi 长度固定为二字节 (CSI除外) + private val DROP_ANSI_PATTERN = """\u001b[\u0040–\u005F]""".toRegex() /** * 从 [String] 中剔除 ansi 控制符 */ @JvmStatic - public fun String.dropAnsi(): String = DROP_ANSI_PATTERN.replace(this, "") + public fun String.dropAnsi(): String = this + .replace(DROP_CSI_PATTERN, "") // 先进行 CSI 剔除后进行 ANSI 剔除 + .replace(DROP_ANSI_PATTERN, "") /** * 使用 [builder] 封装一个 [AnsiMessageBuilder]