从字符串中删除所有ANSI颜色/样式

Remove all ANSI colors/styles from strings

本文关键字:ANSI 颜色 样式 字符串 删除      更新时间:2023-09-26

我使用一个为字符串添加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);
 });

但是输出是一样的…

应该使用的正则表达式是

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

这匹配大多数ANSI转义码,除了颜色之外,包括扩展的VT100代码,老式/专有打印机代码等。

请注意,上面正则表达式中的'u001b可能不适用于您的特定库(即使它应该);如果不能接受转义字符,请查看我对类似问题的回答。

如果你不喜欢正则表达式,你可以使用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);

转义字符是'u001b,从[到遇到第一个m的顺序是样式。你只需要把它去掉。因此,使用以下模式全局替换:

/'u001b'[.*?m/g

,

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

颜色像ESC[39m格式,最短的regexp是为它的/'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 )