Skip to content

flex-development/ansi-regex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

ansi-regex

ci github release npm npm downloads install size codecov module type: esm license conventional commits typescript vitest yarn

Regular expression for matching ANSI escape codes

Contents

What is this?

This is a tiny, but useful package for matching ANSI escape codes in strings.

Install

This package is ESM only.

In Node.js with yarn:

yarn add @flex-development/ansi-regex
See Git - Protocols | Yarn Β for details regarding installing from Git.

In Deno with esm.sh:

import { ansiRegex } from 'https://esm.sh/@flex-development/ansi-regex'

In browsers with esm.sh:

<script type="module">
  import { ar } from 'https://esm.sh/@flex-development/ansi-regex'
</script>

With bun:

bun add @flex-development/ansi-regex
See bun add for more details.

Use

example.mjs:

import { ansiRegex } from '@flex-development/ansi-regex'
import c from '@flex-development/colors'
import { ok } from 'devlop'

const emojis = 'πŸ¦„πŸ¦ΎπŸš€'
const hello = c.bgBlue(c.bold('hello world 🌎'))

console.log(`${JSON.stringify(emojis)}:`, ansiRegex().test(emojis))
console.log(`${JSON.stringify(hello)}:`, ansiRegex().test(hello))

for (const match of hello.matchAll(ansiRegex({ d: true }))) {
  const { groups, index, indices } = match

  ok(groups, 'expected `groups`')

  console.dir({
    group: Object.entries(groups).reduce((acc, [key, value]) => {
      if (typeof value === 'string') value = hrc(value)
      return acc[key] = value, acc
    }, {}),
    index,
    indices: [...indices]
  }, { sorted: true })
}

/**
 * Make control characters in `string` human-readable.
 *
 * @this {void}
 *
 * @param {string} string
 *  The string containing control characters
 * @return {string}
 *  `string` with human-readable control characters
 */
function hrc(string) {
  /**
   * Regular expression matching control characters.
   *
   * @const {RegExp} controls
   */
  const controls = /[\u0000-\u001F\u007F-\u009F]/g

  return string.replace(controls, hr)

  /**
   * Convert a control `character` to a human-readable string.
   *
   * @this {void}
   *
   * @param {string} character
   *  The control character
   * @return {string}
   *  The control `character` as a human-readable string
   */
  function hr(character) {
    return `\\u${character.codePointAt(0).toString(16).padStart(4, '0')}`
  }
}

...yields

"πŸ¦„πŸ¦ΎπŸš€": false
"\u001b[44m\u001b[1mhello world 🌎\u001b[22m\u001b[49m": true
{
  group: {
    ansi: '\\u001b[44m',
    csi: '\\u001b[44m',
    csi_final: 'm',
    csi_intermediate: '',
    csi_introducer: '\\u001b',
    csi_params: '44',
    esc: undefined,
    esc_final: undefined,
    osc: undefined,
    osc_command: undefined,
    osc_data: undefined,
    osc_introducer: undefined,
    osc_sep: undefined,
    osc_terminator: undefined
  },
  index: 0,
  indices: [
    [ 0, 5 ],
    [ 0, 5 ],
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    [ 0, 5 ],
    [ 0, 1 ],
    [ 2, 4 ],
    [ 4, 4 ],
    [ 4, 5 ],
    undefined,
    undefined
  ]
}
{
  group: {
    ansi: '\\u001b[1m',
    csi: '\\u001b[1m',
    csi_final: 'm',
    csi_intermediate: '',
    csi_introducer: '\\u001b',
    csi_params: '1',
    esc: undefined,
    esc_final: undefined,
    osc: undefined,
    osc_command: undefined,
    osc_data: undefined,
    osc_introducer: undefined,
    osc_sep: undefined,
    osc_terminator: undefined
  },
  index: 5,
  indices: [
    [ 5, 9 ],
    [ 5, 9 ],
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    [ 5, 9 ],
    [ 5, 6 ],
    [ 7, 8 ],
    [ 8, 8 ],
    [ 8, 9 ],
    undefined,
    undefined
  ]
}
{
  group: {
    ansi: '\\u001b[22m',
    csi: '\\u001b[22m',
    csi_final: 'm',
    csi_intermediate: '',
    csi_introducer: '\\u001b',
    csi_params: '22',
    esc: undefined,
    esc_final: undefined,
    osc: undefined,
    osc_command: undefined,
    osc_data: undefined,
    osc_introducer: undefined,
    osc_sep: undefined,
    osc_terminator: undefined
  },
  index: 23,
  indices: [
    [ 23, 28 ],
    [ 23, 28 ],
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    [ 23, 28 ],
    [ 23, 24 ],
    [ 25, 27 ],
    [ 27, 27 ],
    [ 27, 28 ],
    undefined,
    undefined
  ]
}
{
  group: {
    ansi: '\\u001b[49m',
    csi: '\\u001b[49m',
    csi_final: 'm',
    csi_intermediate: '',
    csi_introducer: '\\u001b',
    csi_params: '49',
    esc: undefined,
    esc_final: undefined,
    osc: undefined,
    osc_command: undefined,
    osc_data: undefined,
    osc_introducer: undefined,
    osc_sep: undefined,
    osc_terminator: undefined
  },
  index: 28,
  indices: [
    [ 28, 33 ],
    [ 28, 33 ],
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    [ 28, 33 ],
    [ 28, 29 ],
    [ 30, 32 ],
    [ 32, 32 ],
    [ 32, 33 ],
    undefined,
    undefined
  ]
}

API

This package exports the following identifiers:

The default export is ar.

ansiRegex([flags])

Create a regular expression matching ANSI escape codes.

Parameters

  • flags (Flags | null | undefined) β€” an object representing the regular expression flags to apply

Returns

(RegExp) New regular expression matching ANSI escape codes

ar

(RegExp)

The default regular expression matching ANSI escape codes.

Types

This package is fully typed with TypeScript.

Flags

Record, where each key is a regular expression flag and each truthy value indicates if the flag should be applied to the regular expression (interface).

interface Flags {/* see code */}

When developing extensions that use additional flags, augment Flags to register custom flags:

declare module '@flex-development/ansi-regex' {
  interface Flags {
    i?: boolean | null | undefined
  }
}

Properties

  • d? (boolean | null | undefined) β€” whether to generate indices for substring matches

    πŸ‘€ RegExp#hasIndices

  • g? (boolean | null | undefined) β€” whether to perform global search

    πŸ‘€ RegExp#global

  • u? (boolean | null | undefined) β€” whether to treat a pattern as a sequence of unicode code points

    πŸ‘€ RegExp#unicode

  • v? (boolean | null | undefined) β€” whether to treat a pattern as a sequence of unicode code points.\

    πŸ‘‰ the v flag is an "upgrade" to the u flag that enables additional unicode-related features. because u and v interpret the same regex in incompatible ways, enabling both flags at once results in a SyntaxError
    πŸ‘€ RegExp#unicodeSets

  • y? (boolean | null | undefined) β€” whether to start matches at the current position in the target string

    πŸ‘€ RegExp#sticky

Contribute

See CONTRIBUTING.md.

This project has a code of conduct. By interacting with this repository, organization, or community you agree to abide by its terms.

Sponsor this project

 

Packages

 
 
 

Contributors 3

  •  
  •  
  •