49

I use a library that adds ANSI colors / styles to strings. For example:

> "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'

When I do:

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

a "Hello World" white and bold message will be output.

Having a string like '\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m' how can these elements be removed?

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

Maybe a good regular expression? Or is there any built-in feature?


The work around I was thinking was to create child process:

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);
 });

But the output is the same...

Ionică Bizău
  • 109,027
  • 88
  • 289
  • 474
  • You should use [chalk](http://github.com/chalk/chalk). It checks for colors being enabled or not and will automatically strip ANSI codes from your text. – Qix - MONICA WAS MISTREATED Jun 30 '15 at 20:21
  • @Qix It's not about styling, it's about *unstyling* -- removing the ANSI styles from strings. For coloring, I use [`couleurs`](https://github.com/IonicaBizau/node-couleurs) and for unstyling I use [`ansi-parser`](https://github.com/IonicaBizau/node-ansi-parser). Hope it's now clearer. – Ionică Bizău Jul 01 '15 at 06:47
  • `I use a library that adds ANSI colors / styles to strings` And I'm saying by using chalk, you can remove those codes automatically if you so choose (i.e. you can style *and* automatically remove). – Qix - MONICA WAS MISTREATED Jul 01 '15 at 10:36
  • 1
    @Qix Ah, I've got it. I thought `chalk` is only for coloring. From what I see, [`strip-ansi`](https://github.com/chalk/strip-ansi) is used for this, and you are one of the contributors. :-) Nice! – Ionică Bizău Jul 01 '15 at 13:45
  • I am now; wasn't when I originally posted haha. Came back to update the regex with the one I wrote for [`ansi-regex`](https://github.com/chalk/ansi-regex). – Qix - MONICA WAS MISTREATED Jul 01 '15 at 13:46
  • 1
    @Qix You could update your answer including the `strip-ansi` package. I always liked tiny and cute npm packages. :) – Ionică Bizău Jul 01 '15 at 13:56

3 Answers3

108

The regex you should be using is

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

This matches most of the ANSI escape codes, beyond just colors, including the extended VT100 codes, archaic/proprietary printer codes, etc.

Note that the \u001b in the above regex may not work for your particular library (even though it should); check out my answer to a similar question regarding acceptable escape characters if it doesn't.

If you don't like regexes, you can always use the strip-ansi package.


For instance, the string jumpUpAndRed below contains ANSI codes for jumping to the previous line, writing some red text, and then going back to the beginning of the next line - of which require suffixes other than 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);
user229044
  • 232,980
  • 40
  • 330
  • 338
Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
15

The escape character is \u001b, and the sequence from [ until first m is encountered is the styling. You just need to remove that. So, replace globally using the following pattern:

/\u001b\[.*?m/g

Thus,

'\u001b[1m\u001b[38;5;231mHello World\u001b[0m\u001b[22m'.replace(/\u001b\[.*?m/g, '')
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
4

The colors are like ESC[39m format, the shortest regexp is for it the /\u001b[^m]*?m/g

Where \u001b is the ESC character, [^m]*? is any character(s) till m (not greedy pattern), the m itself, and /g for global (all) replace.

Example:

    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 )