【问题标题】:Remove all ANSI colors/styles from strings从字符串中删除所有 ANSI 颜色/样式
【发布时间】:2014-10-04 10:12:39
【问题描述】:

use a library 将 ANSI 颜色/样式添加到字符串。例如:

> "Hello World".rgb(255, 255, 255)
'\u001b[38;5;231mHello World\u001b[0m'
> "Hello World".rgb(255, 255, 255).bold()
'\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m'

当我这样做时:

console.log('\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m')

将输出一条"Hello World" 白色和粗体消息。

有一个像'\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m' 这样的字符串如何删除这些元素?

foo('\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m') //=> "Hello World"

也许是一个好的正则表达式?还是有什么内置功能?


我正在考虑的工作是创建子进程:

require("child_process")
 .exec("node -pe \"console.error('\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m')\""
 , function (err, stderr, stdout) { console.log(stdout);
 });

但是输出是一样的……

【问题讨论】:

  • 你应该使用chalk。它会检查是否启用了颜色,并会自动从您的文本中去除 ANSI 代码。
  • @Qix 这不是关于样式,而是关于 unstyling -- 从字符串中删除 ANSI 样式。对于着色,我使用couleurs,对于取消样式我使用ansi-parser。希望现在更清楚了。
  • I use a library that adds ANSI colors / styles to strings 我是说通过使用粉笔,如果您愿意,您可以自动删除这些代码(即您可以设置样式自动删除)。
  • @Qix 啊,我明白了。我以为chalk 仅用于着色。据我所知,strip-ansi 用于此目的,您是贡献者之一。 :-) 不错!
  • @Qix 您可以更新您的答案,包括strip-ansi 包。我一直喜欢小巧可爱的 npm 包。 :)

标签: javascript regex node.js ansi-escape


【解决方案1】:

颜色类似于 ESC[39m 格式,最短的正则表达式是 /\u001b[^m]*?m/g

其中 \u001bESC 字符, [^m]*? 是直到 m 的任何字符(不是贪婪模式), m 本身,以及 /g 用于全局(全部)替换。

例子:

    var line="\x1B[90m2021-02-03 09:35:50.323\x1B[39m\t\x1B[97mFinding: \x1B[39m\x1B[97m»\x1B[39m\x1B[33m42125121242\x1B[39m\x1B[97m«\x1B[39m\x1B[0m\x1B[0m\t\x1B[92mOK\x1B[39m";
    
    console.log(line.replace(/\u001b[^m]*?m/g,""));
// ->  2021-02-03 09:35:50.323 Finding: »42125121242«  OK ( without colors )
    console.log(line);
// -> 2021-02-03 09:35:50.323 Finding: »42125121242«  OK ( colored )

【讨论】:

    【解决方案2】:

    regex you should be using

    /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g
    

    这与大多数ANSI escape codes 匹配,不仅仅是颜色,包括扩展的 VT100 代码、古老/专有打印机代码等。

    请注意,上述正则表达式中的\u001b 可能不适用于您的特定库(即使它应该);如果没有,请查看my answer 以了解有关可接受的转义字符的类似问题。

    如果您不喜欢正则表达式,您可以随时使用strip-ansi 包。


    例如,下面的字符串 jumpUpAndRed 包含 ANSI 代码,用于跳转到上一行,写入一些红色文本,然后返回到下一行的开头 - 其中需要 m 以外的后缀。

    var jumpUpAndRed = "\x1b[F\x1b[31;1mHello, there!\x1b[m\x1b[E";
    var justText = jumpUpAndRed.replace(
        /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');
    console.log(justText);

    【讨论】:

    • 完全披露:我是上述粉笔项目的维护者
    【解决方案3】:

    转义字符是\u001b,并且遇到从[ 到第一个m 的序列就是样式。你只需要删除它。因此,请使用以下模式进行全局替换:

    /\u001b\[.*?m/g
    

    因此,

    '\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m'.replace(/\u001b\[.*?m/g, '')
    

    【讨论】:

      猜你喜欢
      • 2016-07-21
      • 1970-01-01
      • 2015-05-28
      • 2018-10-23
      • 2015-03-07
      • 1970-01-01
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多