Repository: nodejs/node
Pull request: util,console: colorize regexp groups, character classes, etc

This adds a parser to parse the regular expression and to highlight different parts of a regular expression in case colors are active.

It is a one time pass algorithm and should therefore not cause too much overhead during parsing.

As side effect, it is now possible to create individual styles to colorize inspected values values as a user likes. This might for example be expanded to numbers with numeric separators, highlighting the separators or decimal points different.

It would in theory also be possible to return a changed string. That is however not the intention for this API as it is only triggered in case colors are active.

I used a very fine granular differentiation to highlight all differences and to make sure key characters are visible fast.
I decided to handle it with a depth instead of fixed groups that define the color for the group. I think this is an improvement over the current implementation either way and we could still change it later, if it is deemed better to have fixed colors instead.

<img width="990" height="758" alt="image" src="https://github.com/user-attachments/assets/ba9c6378-1109-45ed-976b-2fef8bc294db" />

I know of one case that this is not showing correct: if a unicode property is seemingly started, while not being one without the u or v flag and it also containing a seemingly legitimate ending.

<img width="544" height="46" alt="image" src="https://github.com/user-attachments/assets/8047bfdf-09ab-4b6f-83bd-98a0423c7934" />

Changed files:
filename: doc/api/util.md
patch: @@ -847,6 +847,11 @@ stream.write('With ES6');
 <!-- YAML
 added: v0.3.0
 changes:
+  - version:
+    - REPLACEME
+    pr-url: https://github.com/nodejs/node/pull/59710
+    description: The util.inspect.styles.regexp style is now a method that is
+                 invoked for coloring the stringified regular expression.
   - version:
     - v17.3.0
     - v16.14.0
@@ -1297,7 +1302,12 @@ The default styles and associated colors are:
 * `name`: (no styling)
 * `null`: `bold`
 * `number`: `yellow`
-* `regexp`: `red`
+* `regexp`: A method that colors character classes, groups, assertions, and
+  other parts for improved readability. To customize the coloring, change the
+  `colors` property. It is set to
+  `['red', 'green', 'yellow', 'cyan', 'magenta']` by default and may be
+  adjusted as needed. The array is repetitively iterated through depending on
+  the "depth".
 * `special`: `cyan` (e.g., `Proxies`)
 * `string`: `green`
 * `symbol`: `green`
@@ -1309,6 +1319,17 @@ terminals. To verify color support use [`tty.hasColors()`][].
 Predefined control codes are listed below (grouped as "Modifiers", "Foreground
 colors", and "Background colors").
 
+#### Complex custom coloring
+
+It is possible to define a method as style. It receives the stringified value
+of the input. It is invoked in case coloring is active and the type is
+inspected.
+
+Example: `util.inspect.styles.regexp(value)`
+
+* `value` {string} The string representation of the input type.
+* Returns: {string} The adjusted representation of `object`.
+
 #### Modifiers
 
 Modifier support varies throughout different terminals. They will mostly be

filename: lib/internal/util/inspect.js
patch: @@ -502,7 +502,6 @@ defineColorAlias('inverse', 'swapColors');
 defineColorAlias('inverse', 'swapcolors');
 defineColorAlias('doubleunderline', 'doubleUnderline');
 
-// TODO(BridgeAR): Add function style support for more complex styles.
 // Don't use 'blue' not visible on cmd.exe
 inspect.styles = ObjectAssign({ __proto__: null }, {
   special: 'cyan',
@@ -515,11 +514,259 @@ inspect.styles = ObjectAssign({ __proto__: null }, {
   symbol: 'green',
   date: 'magenta',
   // "name": intentionally not styling
-  // TODO(BridgeAR): Highlight regular expressions properly.
-  regexp: 'red',
+  regexp: highlightRegExp,
   module: 'underline',
 });
 
+// Define the palette for RegExp group depth highlighting. Can be changed by users.
+inspect.styles.regexp.colors = ['green', 'red', 'yellow', 'cyan', 'magenta'];
+
+const highlightRegExpColors = inspect.styles.regexp.colors.slice();
+
+/**
+ * Colorize a JavaScript RegExp pattern per ECMAScript grammar.
+ * This is a tolerant single-pass highlighter using heuristics in some cases.
+ * It supports: groups (named/unnamed, lookaround), assertions, alternation,
+ * quantifiers, escapes (incl. Unicode properties), character classes and
+ * backreferences.
+ * @param {string} regexpString
+ * @returns {string}
+ */
+function highlightRegExp(regexpString) {
+  let out = '';
+  let i = 0;
+  let depth = 0;
+  let inClass = false;
+
+  // TODO(BridgeAR): Add group type tracking. That allows to increase the depth
+  // in case the same type is next to each other.
+  // let groupType = 0;
+
+  // Verify palette and update cache if user changed colors
+  const paletteNames = highlightRegExp.colors?.length > 0 ?
+    highlightRegExp.colors :
+    highlightRegExpColors;
+
+  const palette = paletteNames.reduce((acc, name) => {
+    const color = inspect.colors[name];
+    if (color) acc.push([`\u001b[${color[0]}m`, `\u001b[${color[1]}m`]);
+    return acc;
+  }, []);
+
+  function writeGroup(start, end, decreaseDepth = 1) {
+    let seq = '';
+    i++;
+    // Only checking for the closing delimiter is a fast heuristic for regular
+    // expressions without the u or v flag. A safer check would verify that the
+    // read characters are all alphanumeric.
+    while (i < regexpString.length && regexpString[i] !== end) {
+      seq += regexpString[i++];
+    }
+    if (i < regexpString.length) {
+      depth -= decreaseDepth;
+      write(start);
+      writeDepth(seq, 1, 1);
+      write(end);
+      depth += decreaseDepth;
+    } else {
+      // The group is not closed which would lead to mistakes in the output.
+      // This is a workaround to prevent output from being corrupted.
+      writeDepth(start, 1, -seq.length);
+    }
+  }
+
+  const write = (str) => {
+    const idx = depth % palette.length;
+    // Safeguard against bugs in the implementation.
+    const color = palette[idx] ?? palette[0];
+    out += color[0] + str + color[1];
+    return idx;
+  };
+
+  function writeDepth(str, incDepth, incI) {
+    depth += incDepth;
+    write(str);
+    depth -= incDepth;
+    i += incI;
+  }
+
+  // Opening '/'
+  write('/');
+  depth++;
+  i = 1;
+
+  // Parse pattern until next unescaped '/'
+  while (i < regexpString.length) {
+    const ch = regexpString[i];
+
+    if (inClass) {
+      if (ch === '\\') {
+        let seq = '\\';
+        i++;
+        if (i < regexpString.length) {
+          seq += regexpString[i++];
+          const next = seq[1];
+          if (next === 'u' && regexpString[i] === '{') {
+            writeGroup(`${seq}{`, '}', 0);
+            continue;
+          } else if ((next === 'p' || next === 'P') && regexpString[i] === '{') {
+            writeGroup(`${seq}{`, '}', 0);
+            continue;
+          } else if (seq[1] === 'x') {
+            seq += regexpString.slice(i, i + 2);
+            i += 2;
+          }
+        }
+        write(seq);
+      } else if (ch === ']') {
+        depth--;
+        write(']');
+        i++;
+        inClass = false;
+      } else if (ch === '-' && regexpString[i - 1] !== '[' &&
+                 i + 1 < regexpString.length && regexpString[i + 1] !== ']') {
+        writeDepth('-', 1, 1);
+      } else {
+        write(ch);
+        i++;
+      }
+    } else if (ch === '[') {
+      // Enter class
+      write('[');
+      depth++;
+      i++;
+      inClass = true;
+    } else if (ch === '(') {
+      write('(');
+      depth++;
+      i++;
+      if (i < regexpString.length && regexpString[i] === '?') {
+        // Assertions and named groups
+        i++;
+        const a = i < regexpString.length ? regexpString[i] : '';
+        if (a === ':' || a === '=' || a === '!') {
+          writeDepth(`?${a}`, -1, 1);
+        } else {
+          const b = i + 1 < regexpString.length ? regexpString[i + 1] : '';
+          if (a === '<' && (b === '=' || b === '!')) {
+            writeDepth(`?<${b}`, -1, 2);
+          } else if (a === '<') {
+            // Named capture: write '?<name>' as a single colored token
+            i++; // consume '<'
+            const start = i;
+            while (i < regexpString.length && regexpString[i] !== '>') {
+              i++;
+            }
+            const name = regexpString.slice(start, i);
+            if (i < regexpString.length && regexpString[i] === '>') {
+              depth--;
+              write('?<');
+              writeDepth(name, 1, 0);
+              write('>');
+              depth++;
+              i++;
+            } else {
+              writeDepth('?<', -1, 0);
+              write(name);
+            }
+          } else {
+            write('?');
+          }
+        }
+      }
+    } else if (ch === ')') {
+      depth--;
+      write(')');
+      i++;
+    } else if (ch === '\\') {
+      let seq = '\\';
+      i++;
+      if (i < regexpString.length) {
+        seq += regexpString[i++];
+        const next = seq[1];
+        if (i < regexpString.length) {
+          if (next === 'u' && regexpString[i] === '{') {
+            writeGroup(`${seq}{`, '}', 0);
+            continue;
+          } else if (next === 'x') {
+            seq += regexpString.slice(i, i + 2);
+            i += 2;
+          } else if (next >= '0' && next <= '9') {
+            while (i < regexpString.length && regexpString[i] >= '0' && regexpString[i] <= '9') {
+              seq += regexpString[i++];
+            }
+          } else if (next === 'k' && regexpString[i] === '<') {
+            writeGroup(`${seq}<`, '>');
+            continue;
+          } else if ((next === 'p' || next === 'P') && regexpString[i] === '{') {
+            // Unicode properties
+            writeGroup(`${seq}{`, '}', 0);
+            continue;
+          }
+        }
+      }
+      writeDepth(seq, 1, 0);
+    } else if (ch === '|' || ch === '+' || ch === '*' || ch === '?' || ch === ',' || ch === '^' || ch === '$') {
+      writeDepth(ch, 3, 1);
+    } else if (ch === '{') {
+      i++;
+      let digits = '';
+      while (i < regexpString.length && regexpString[i] >= '0' && regexpString[i] <= '9') {
+        digits += regexpString[i++];
+      }
+      if (digits) {
+        write('{');
+        depth++;
+        writeDepth(digits, 1, 0);
+      }
+      if (i < regexpString.length) {
+        if (regexpString[i] === ',') {
+          if (!digits) {
+            write('{');
+            depth++;
+          }
+          write(',');
+          i++;
+        } else if (!digits) {
+          depth += 1;
+          write('{');
+          depth -= 1;
+          continue;
+        }
+      }
+      let digits2 = '';
+      while (i < regexpString.length && regexpString[i] >= '0' && regexpString[i] <= '9') {
+        digits2 += regexpString[i++];
+      }
+      if (digits2) {
+        writeDepth(digits2, 1, 0);
+      }
+      if (i < regexpString.length && regexpString[i] === '}') {
+        depth--;
+        write('}');
+        i++;
+      }
+      if (i < regexpString.length && regexpString[i] === '?') {
+        writeDepth('?', 3, 1);
+      }
+    } else if (ch === '.') {
+      writeDepth(ch, 2, 1);
+    } else if (ch === '/') {
+      // Stop at closing delimiter (unescaped, outside of character class)
+      break;
+    } else {
+      writeDepth(ch, 1, 1);
+    }
+  }
+
+  // Closing delimiter and flags
+  writeDepth('/', -1, 1);
+  if (i < regexpString.length) {
+    write(regexpString.slice(i));
+  }
+  return out;
+}
+
 function addQuotes(str, quotes) {
   if (quotes === -1) {
     return `"${str}"`;
@@ -606,8 +853,12 @@ function stylizeWithColor(str, styleType) {
   const style = inspect.styles[styleType];
   if (style !== undefined) {
     const color = inspect.colors[style];
-    if (color !== undefined)
+    if (color !== undefined) {
       return `\u001b[${color[0]}m${str}\u001b[${color[1]}m`;
+    }
+    if (typeof style === 'function') {
+      return style(str);
+    }
   }
   return str;
 }
@@ -1048,9 +1299,10 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
       const prefix = getPrefix(constructor, tag, 'RegExp');
       if (prefix !== 'RegExp ')
         base = `${prefix}${base}`;
+      base = ctx.stylize(base, 'regexp');
       if ((keys.length === 0 && protoProps === undefined) ||
           (recurseTimes > ctx.depth && ctx.depth !== null)) {
-        return ctx.stylize(base, 'regexp');
+        return base;
       }
     } else if (isDate(value)) {
       // Make dates with properties first say the date

filename: test/parallel/test-util-inspect-regexp.js
patch: @@ -0,0 +1,150 @@
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const util = require('util');
+
+util.inspect.defaultOptions.compact = 5;
+util.inspect.defaultOptions.breakLength = Infinity;
+
+function expectColored([regexp, expected]) {
+  if (!common.hasIntl && !regexp) {
+    return;
+  }
+  const colored = util.inspect(regexp, { colors: true });
+  const plain = util.inspect(regexp, { colors: false });
+  try {
+    assert.strictEqual(util.stripVTControlCharacters(colored), plain);
+    assert.strictEqual(colored, expected, `${regexp} failed`);
+  } catch (error) {
+    console.log('\nInspecting regular expression', colored, '\n');
+    throw error;
+  }
+}
+
+function createRegExp(string, flags) {
+  if (common.hasIntl) {
+    return new RegExp(string, flags);
+  }
+}
+
+/* eslint-disable node-core/no-unescaped-regexp-dot */
+/* eslint-disable @stylistic/js/max-len */
+
+// Comprehensive set of regexes covering branches in highlightRegExp
+const tests = [
+  [/a/, '\x1B[32m/\x1B[39m\x1B[33ma\x1B[39m\x1B[32m/\x1B[39m'],
+  [/a|b/, '\x1B[32m/\x1B[39m\x1B[33ma\x1B[39m\x1B[35m|\x1B[39m\x1B[33mb\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<year>\d{4})-(?<mon>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])$/u, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33myear\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m4\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[33m-\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mmon\x1B[39m\x1B[31m>\x1B[39m\x1B[36m0\x1B[39m\x1B[33m[\x1B[39m\x1B[36m1\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[33m]\x1B[39m\x1B[32m|\x1B[39m\x1B[36m1\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m2\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[33m-\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mday\x1B[39m\x1B[31m>\x1B[39m\x1B[36m0\x1B[39m\x1B[33m[\x1B[39m\x1B[36m1\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[33m]\x1B[39m\x1B[32m|\x1B[39m\x1B[33m[\x1B[39m\x1B[36m1\x1B[39m\x1B[36m2\x1B[39m\x1B[33m]\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m|\x1B[39m\x1B[36m3\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[36m1\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [/^(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{12,}$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[36m\\d\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m\\w\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[36m.\x1B[39m\x1B[31m{\x1B[39m\x1B[36m12\x1B[39m\x1B[33m,\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b(?<!\$)\d{1,3}(?:,\d{3})*(?:\.\d+)?\b/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<!\x1B[39m\x1B[36m\\$\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\d\x1B[39m\x1B[31m{\x1B[39m\x1B[36m1\x1B[39m\x1B[33m,\x1B[39m\x1B[36m3\x1B[39m\x1B[31m}\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[32m,\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[35m*\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\.\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[33m\\b\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b\w+(?=\s*:\s)/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[33m\\w\x1B[39m\x1B[35m+\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[36m\\s\x1B[39m\x1B[32m*\x1B[39m\x1B[36m:\x1B[39m\x1B[36m\\s\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?:https?:\/\/)?(?:www\.)?[\w.-]+\.[A-Za-z]{2,}(?:\/[^\s?#]*)?(?:\?[^\s#]*)?(?:#[^\s]*)?$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36mh\x1B[39m\x1B[36mt\x1B[39m\x1B[36mt\x1B[39m\x1B[36mp\x1B[39m\x1B[36ms\x1B[39m\x1B[32m?\x1B[39m\x1B[36m:\x1B[39m\x1B[36m\\/\x1B[39m\x1B[36m\\/\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36mw\x1B[39m\x1B[36mw\x1B[39m\x1B[36mw\x1B[39m\x1B[36m\\.\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m[\x1B[39m\x1B[33m\\w\x1B[39m\x1B[33m.\x1B[39m\x1B[33m-\x1B[39m\x1B[31m]\x1B[39m\x1B[35m+\x1B[39m\x1B[33m\\.\x1B[39m\x1B[31m[\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mZ\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[31m]\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[33m,\x1B[39m\x1B[31m}\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\/\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m\\s\x1B[39m\x1B[36m?\x1B[39m\x1B[36m#\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\?\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m\\s\x1B[39m\x1B[36m#\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m#\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<ip>(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3})$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mip\x1B[39m\x1B[31m>\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m2\x1B[39m\x1B[35m5\x1B[39m\x1B[36m[\x1B[39m\x1B[35m0\x1B[39m\x1B[32m-\x1B[39m\x1B[35m5\x1B[39m\x1B[36m]\x1B[39m\x1B[31m|\x1B[39m\x1B[35m2\x1B[39m\x1B[36m[\x1B[39m\x1B[35m0\x1B[39m\x1B[32m-\x1B[39m\x1B[35m4\x1B[39m\x1B[36m]\x1B[39m\x1B[35m\\d\x1B[39m\x1B[31m|\x1B[39m\x1B[35m1\x1B[39m\x1B[31m?\x1B[39m\x1B[35m\\d\x1B[39m\x1B[31m?\x1B[39m\x1B[35m\\d\x1B[39m\x1B[33m)\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m\\.\x1B[39m\x1B[36m(\x1B[39m\x1B[36m?:\x1B[39m\x1B[32m2\x1B[39m\x1B[32m5\x1B[39m\x1B[35m[\x1B[39m\x1B[32m0\x1B[39m\x1B[31m-\x1B[39m\x1B[32m5\x1B[39m\x1B[35m]\x1B[39m\x1B[33m|\x1B[39m\x1B[32m2\x1B[39m\x1B[35m[\x1B[39m\x1B[32m0\x1B[39m\x1B[31m-\x1B[39m\x1B[32m4\x1B[39m\x1B[35m]\x1B[39m\x1B[32m\\d\x1B[39m\x1B[33m|\x1B[39m\x1B[32m1\x1B[39m\x1B[33m?\x1B[39m\x1B[32m\\d\x1B[39m\x1B[33m?\x1B[39m\x1B[32m\\d\x1B[39m\x1B[36m)\x1B[39m\x1B[33m)\x1B[39m\x1B[33m{\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<h>[0-1]?\d|2[0-3]):(?<m>[0-5]\d)(?::(?
[0-5]\d))?$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mh\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m1\x1B[39m\x1B[33m]\x1B[39m\x1B[32m?\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m|\x1B[39m\x1B[36m2\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m3\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[33m:\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mm\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m5\x1B[39m\x1B[33m]\x1B[39m\x1B[36m\\d\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m:\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?<\x1B[39m\x1B[36ms\x1B[39m\x1B[33m>\x1B[39m\x1B[36m[\x1B[39m\x1B[35m0\x1B[39m\x1B[32m-\x1B[39m\x1B[35m5\x1B[39m\x1B[36m]\x1B[39m\x1B[35m\\d\x1B[39m\x1B[33m)\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?:(?!cat).)*$/s, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?!\x1B[39m\x1B[35mc\x1B[39m\x1B[35ma\x1B[39m\x1B[35mt\x1B[39m\x1B[33m)\x1B[39m\x1B[35m.\x1B[39m\x1B[31m)\x1B[39m\x1B[35m*\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31ms\x1B[39m'],
+  [/^(?:\+?\d{1,3}[-.\s]?)?(?:\(?\d{2,4}\)?[-.\s]?)?\d{3,4}[-.\s]?\d{3,4}$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\+\x1B[39m\x1B[32m?\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m1\x1B[39m\x1B[36m,\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[33m[\x1B[39m\x1B[36m-\x1B[39m\x1B[36m.\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[32m?\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\(\x1B[39m\x1B[32m?\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[36m,\x1B[39m\x1B[35m4\x1B[39m\x1B[33m}\x1B[39m\x1B[36m\\)\x1B[39m\x1B[32m?\x1B[39m\x1B[33m[\x1B[39m\x1B[36m-\x1B[39m\x1B[36m.\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[32m?\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[33m\\d\x1B[39m\x1B[31m{\x1B[39m\x1B[36m3\x1B[39m\x1B[33m,\x1B[39m\x1B[36m4\x1B[39m\x1B[31m}\x1B[39m\x1B[31m[\x1B[39m\x1B[33m-\x1B[39m\x1B[33m.\x1B[39m\x1B[33m\\s\x1B[39m\x1B[31m]\x1B[39m\x1B[35m?\x1B[39m\x1B[33m\\d\x1B[39m\x1B[31m{\x1B[39m\x1B[36m3\x1B[39m\x1B[33m,\x1B[39m\x1B[36m4\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b(0[xX])(?<hex>[0-9A-Fa-f]+)\b/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[36m0\x1B[39m\x1B[33m[\x1B[39m\x1B[36mx\x1B[39m\x1B[36mX\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mhex\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mF\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mf\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\b\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b(?<num>\d+)\.(?<frac>\d+)\b/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mnum\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\.\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mfrac\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\b\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b([A-Za-z]+)\s+\1\b/i, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\s\x1B[39m\x1B[35m+\x1B[39m\x1B[33m\\1\x1B[39m\x1B[33m\\b\x1B[39m\x1B[32m/\x1B[39m\x1B[31mi\x1B[39m'],
+  [/^([A-Za-z]\w*)(?:\s*,\s*\1)*$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[33m]\x1B[39m\x1B[36m\\w\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\s\x1B[39m\x1B[32m*\x1B[39m\x1B[32m,\x1B[39m\x1B[36m\\s\x1B[39m\x1B[32m*\x1B[39m\x1B[36m\\1\x1B[39m\x1B[31m)\x1B[39m\x1B[35m*\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^\s*(?!<\/?script\b).*<\/?[A-Za-z][^>]*>\s*$/is, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[33m\\s\x1B[39m\x1B[35m*\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?!\x1B[39m\x1B[36m<\x1B[39m\x1B[36m\\/\x1B[39m\x1B[32m?\x1B[39m\x1B[36ms\x1B[39m\x1B[36mc\x1B[39m\x1B[36mr\x1B[39m\x1B[36mi\x1B[39m\x1B[36mp\x1B[39m\x1B[36mt\x1B[39m\x1B[36m\\b\x1B[39m\x1B[31m)\x1B[39m\x1B[36m.\x1B[39m\x1B[35m*\x1B[39m\x1B[33m<\x1B[39m\x1B[33m\\/\x1B[39m\x1B[35m?\x1B[39m\x1B[31m[\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mZ\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[31m]\x1B[39m\x1B[31m[\x1B[39m\x1B[33m^\x1B[39m\x1B[33m>\x1B[39m\x1B[31m]\x1B[39m\x1B[35m*\x1B[39m\x1B[33m>\x1B[39m\x1B[33m\\s\x1B[39m\x1B[35m*\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mis\x1B[39m'],
+  [/^(?:\r\n|[\n\r\u2028\u2029])+$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\r\x1B[39m\x1B[36m\\n\x1B[39m\x1B[32m|\x1B[39m\x1B[33m[\x1B[39m\x1B[36m\\n\x1B[39m\x1B[36m\\r\x1B[39m\x1B[36m\\u\x1B[39m\x1B[36m2\x1B[39m\x1B[36m0\x1B[39m\x1B[36m2\x1B[39m\x1B[36m8\x1B[39m\x1B[36m\\u\x1B[39m\x1B[36m2\x1B[39m\x1B[36m0\x1B[39m\x1B[36m2\x1B[39m\x1B[36m9\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<oct>[0-7]+)$|^(?<bin>[01]+)b$|^(?<hex>[0-9A-Fa-f]+)h$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33moct\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m7\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[35m|\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mbin\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[36m1\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33mb\x1B[39m\x1B[35m$\x1B[39m\x1B[35m|\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mhex\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mF\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mf\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33mh\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?!.*(.)\1\1)[A-Za-z0-9]{8,}$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?!\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[33m(\x1B[39m\x1B[32m.\x1B[39m\x1B[33m)\x1B[39m\x1B[36m\\1\x1B[39m\x1B[36m\\1\x1B[39m\x1B[31m)\x1B[39m\x1B[31m[\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mZ\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[33m0\x1B[39m\x1B[36m-\x1B[39m\x1B[33m9\x1B[39m\x1B[31m]\x1B[39m\x1B[31m{\x1B[39m\x1B[36m8\x1B[39m\x1B[33m,\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b(?:(?:19|20)\d{2})-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\b(?![^<]*>)/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m1\x1B[39m\x1B[35m9\x1B[39m\x1B[31m|\x1B[39m\x1B[35m2\x1B[39m\x1B[35m0\x1B[39m\x1B[33m)\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[33m-\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m0\x1B[39m\x1B[33m[\x1B[39m\x1B[36m1\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[33m]\x1B[39m\x1B[32m|\x1B[39m\x1B[36m1\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m2\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[33m-\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m0\x1B[39m\x1B[33m[\x1B[39m\x1B[36m1\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[33m]\x1B[39m\x1B[32m|\x1B[39m\x1B[33m[\x1B[39m\x1B[36m1\x1B[39m\x1B[36m2\x1B[39m\x1B[33m]\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m|\x1B[39m\x1B[36m3\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[36m1\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?!\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m<\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[36m>\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<user>[A-Za-z0-9._%+-]+)@(?<host>[A-Za-z0-9.-]+\.[A-Za-z]{2,})$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33muser\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[36m.\x1B[39m\x1B[36m_\x1B[39m\x1B[36m%\x1B[39m\x1B[36m+\x1B[39m\x1B[36m-\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m@\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mhost\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[36m.\x1B[39m\x1B[36m-\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[36m\\.\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[33m]\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[36m,\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^\$(?<amt>\d{1,3}(?:,\d{3})*(?:\.\d{2})?)$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[33m\\$\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mamt\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m1\x1B[39m\x1B[36m,\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[31m,\x1B[39m\x1B[35m\\d\x1B[39m\x1B[36m{\x1B[39m\x1B[32m3\x1B[39m\x1B[36m}\x1B[39m\x1B[33m)\x1B[39m\x1B[32m*\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m\\.\x1B[39m\x1B[35m\\d\x1B[39m\x1B[36m{\x1B[39m\x1B[32m2\x1B[39m\x1B[36m}\x1B[39m\x1B[33m)\x1B[39m\x1B[32m?\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b(?<area>\d{3})-(?<ex>\d{3})-(?<line>\d{4})\b/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33marea\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[33m-\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mex\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[33m-\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mline\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m4\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\b\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<open><([A-Za-z][A-Za-z0-9:-]*)\b[^>]*>)(?<inner>[\s\S]*?)<\/\2>$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mopen\x1B[39m\x1B[31m>\x1B[39m\x1B[36m<\x1B[39m\x1B[33m(\x1B[39m\x1B[36m[\x1B[39m\x1B[35mA\x1B[39m\x1B[32m-\x1B[39m\x1B[35mZ\x1B[39m\x1B[35ma\x1B[39m\x1B[32m-\x1B[39m\x1B[35mz\x1B[39m\x1B[36m]\x1B[39m\x1B[36m[\x1B[39m\x1B[35mA\x1B[39m\x1B[32m-\x1B[39m\x1B[35mZ\x1B[39m\x1B[35ma\x1B[39m\x1B[32m-\x1B[39m\x1B[35mz\x1B[39m\x1B[35m0\x1B[39m\x1B[32m-\x1B[39m\x1B[35m9\x1B[39m\x1B[35m:\x1B[39m\x1B[35m-\x1B[39m\x1B[36m]\x1B[39m\x1B[31m*\x1B[39m\x1B[33m)\x1B[39m\x1B[36m\\b\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m>\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[36m>\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33minner\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m\\s\x1B[39m\x1B[36m\\S\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[32m?\x1B[39m\x1B[31m)\x1B[39m\x1B[33m<\x1B[39m\x1B[33m\\/\x1B[39m\x1B[33m\\2\x1B[39m\x1B[33m>\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?=.*\b(cat|dog)\b)(?=.*\b(red|blue)\b).+$/i, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[36m\\b\x1B[39m\x1B[33m(\x1B[39m\x1B[35mc\x1B[39m\x1B[35ma\x1B[39m\x1B[35mt\x1B[39m\x1B[31m|\x1B[39m\x1B[35md\x1B[39m\x1B[35mo\x1B[39m\x1B[35mg\x1B[39m\x1B[33m)\x1B[39m\x1B[36m\\b\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[36m\\b\x1B[39m\x1B[33m(\x1B[39m\x1B[35mr\x1B[39m\x1B[35me\x1B[39m\x1B[35md\x1B[39m\x1B[31m|\x1B[39m\x1B[35mb\x1B[39m\x1B[35ml\x1B[39m\x1B[35mu\x1B[39m\x1B[35me\x1B[39m\x1B[33m)\x1B[39m\x1B[36m\\b\x1B[39m\x1B[31m)\x1B[39m\x1B[36m.\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mi\x1B[39m'],
+  [/^[-+]?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?(?:[eE][-+]?\d+)?$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m[\x1B[39m\x1B[33m-\x1B[39m\x1B[33m+\x1B[39m\x1B[31m]\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[32m|\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m1\x1B[39m\x1B[36m,\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[31m,\x1B[39m\x1B[35m\\d\x1B[39m\x1B[36m{\x1B[39m\x1B[32m3\x1B[39m\x1B[36m}\x1B[39m\x1B[33m)\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\.\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m[\x1B[39m\x1B[36me\x1B[39m\x1B[36mE\x1B[39m\x1B[33m]\x1B[39m\x1B[33m[\x1B[39m\x1B[36m-\x1B[39m\x1B[36m+\x1B[39m\x1B[33m]\x1B[39m\x1B[32m?\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?\d{2}\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{4}$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35mM\x1B[39m\x1B[35mo\x1B[39m\x1B[35mn\x1B[39m\x1B[31m|\x1B[39m\x1B[35mT\x1B[39m\x1B[35mu\x1B[39m\x1B[35me\x1B[39m\x1B[31m|\x1B[39m\x1B[35mW\x1B[39m\x1B[35me\x1B[39m\x1B[35md\x1B[39m\x1B[31m|\x1B[39m\x1B[35mT\x1B[39m\x1B[35mh\x1B[39m\x1B[35mu\x1B[39m\x1B[31m|\x1B[39m\x1B[35mF\x1B[39m\x1B[35mr\x1B[39m\x1B[35mi\x1B[39m\x1B[31m|\x1B[39m\x1B[35mS\x1B[39m\x1B[35ma\x1B[39m\x1B[35mt\x1B[39m\x1B[31m|\x1B[39m\x1B[35mS\x1B[39m\x1B[35mu\x1B[39m\x1B[35mn\x1B[39m\x1B[33m)\x1B[39m\x1B[32m,\x1B[39m\x1B[36m\\s\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[33m\\d\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[31m}\x1B[39m\x1B[33m\\s\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36mJ\x1B[39m\x1B[36ma\x1B[39m\x1B[36mn\x1B[39m\x1B[32m|\x1B[39m\x1B[36mF\x1B[39m\x1B[36me\x1B[39m\x1B[36mb\x1B[39m\x1B[32m|\x1B[39m\x1B[36mM\x1B[39m\x1B[36ma\x1B[39m\x1B[36mr\x1B[39m\x1B[32m|\x1B[39m\x1B[36mA\x1B[39m\x1B[36mp\x1B[39m\x1B[36mr\x1B[39m\x1B[32m|\x1B[39m\x1B[36mM\x1B[39m\x1B[36ma\x1B[39m\x1B[36my\x1B[39m\x1B[32m|\x1B[39m\x1B[36mJ\x1B[39m\x1B[36mu\x1B[39m\x1B[36mn\x1B[39m\x1B[32m|\x1B[39m\x1B[36mJ\x1B[39m\x1B[36mu\x1B[39m\x1B[36ml\x1B[39m\x1B[32m|\x1B[39m\x1B[36mA\x1B[39m\x1B[36mu\x1B[39m\x1B[36mg\x1B[39m\x1B[32m|\x1B[39m\x1B[36mS\x1B[39m\x1B[36me\x1B[39m\x1B[36mp\x1B[39m\x1B[32m|\x1B[39m\x1B[36mO\x1B[39m\x1B[36mc\x1B[39m\x1B[36mt\x1B[39m\x1B[32m|\x1B[39m\x1B[36mN\x1B[39m\x1B[36mo\x1B[39m\x1B[36mv\x1B[39m\x1B[32m|\x1B[39m\x1B[36mD\x1B[39m\x1B[36me\x1B[39m\x1B[36mc\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\s\x1B[39m\x1B[33m\\d\x1B[39m\x1B[31m{\x1B[39m\x1B[36m4\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?:0|[1-9]\d*)(?:\.\d+)?(?:(?:e|E)[-+]?\d+)?$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m0\x1B[39m\x1B[32m|\x1B[39m\x1B[33m[\x1B[39m\x1B[36m1\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[33m]\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\.\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35me\x1B[39m\x1B[31m|\x1B[39m\x1B[35mE\x1B[39m\x1B[33m)\x1B[39m\x1B[33m[\x1B[39m\x1B[36m-\x1B[39m\x1B[36m+\x1B[39m\x1B[33m]\x1B[39m\x1B[32m?\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b(?<maj>\d+)\.(?<min>\d+)\.(?<patch>\d+)(?:-(?<pre>[0-9A-Za-z.-]+))?(?:\+(?<build>[0-9A-Za-z.-]+))?\b/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mmaj\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\.\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mmin\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\.\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mpatch\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m-\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?<\x1B[39m\x1B[36mpre\x1B[39m\x1B[33m>\x1B[39m\x1B[36m[\x1B[39m\x1B[35m0\x1B[39m\x1B[32m-\x1B[39m\x1B[35m9\x1B[39m\x1B[35mA\x1B[39m\x1B[32m-\x1B[39m\x1B[35mZ\x1B[39m\x1B[35ma\x1B[39m\x1B[32m-\x1B[39m\x1B[35mz\x1B[39m\x1B[35m.\x1B[39m\x1B[35m-\x1B[39m\x1B[36m]\x1B[39m\x1B[31m+\x1B[39m\x1B[33m)\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\+\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?<\x1B[39m\x1B[36mbuild\x1B[39m\x1B[33m>\x1B[39m\x1B[36m[\x1B[39m\x1B[35m0\x1B[39m\x1B[32m-\x1B[39m\x1B[35m9\x1B[39m\x1B[35mA\x1B[39m\x1B[32m-\x1B[39m\x1B[35mZ\x1B[39m\x1B[35ma\x1B[39m\x1B[32m-\x1B[39m\x1B[35mz\x1B[39m\x1B[35m.\x1B[39m\x1B[35m-\x1B[39m\x1B[36m]\x1B[39m\x1B[31m+\x1B[39m\x1B[33m)\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[33m\\b\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^#[0-9A-Fa-f]{3}(?:[0-9A-Fa-f]{3})?$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[33m#\x1B[39m\x1B[31m[\x1B[39m\x1B[33m0\x1B[39m\x1B[36m-\x1B[39m\x1B[33m9\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mF\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mf\x1B[39m\x1B[31m]\x1B[39m\x1B[31m{\x1B[39m\x1B[36m3\x1B[39m\x1B[31m}\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m[\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mF\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mf\x1B[39m\x1B[33m]\x1B[39m\x1B[33m{\x1B[39m\x1B[35m3\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\b(?:https?):\/\/(?:(?!\/{2,})[^\s])+\b/, '\x1B[32m/\x1B[39m\x1B[33m\\b\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36mh\x1B[39m\x1B[36mt\x1B[39m\x1B[36mt\x1B[39m\x1B[36mp\x1B[39m\x1B[36ms\x1B[39m\x1B[32m?\x1B[39m\x1B[31m)\x1B[39m\x1B[33m:\x1B[39m\x1B[33m\\/\x1B[39m\x1B[33m\\/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?!\x1B[39m\x1B[35m\\/\x1B[39m\x1B[36m{\x1B[39m\x1B[32m2\x1B[39m\x1B[35m,\x1B[39m\x1B[36m}\x1B[39m\x1B[33m)\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[35m+\x1B[39m\x1B[33m\\b\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?:(?!.*\b(foo).*\b\1\b).)*$/s, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?!\x1B[39m\x1B[32m.\x1B[39m\x1B[31m*\x1B[39m\x1B[35m\\b\x1B[39m\x1B[36m(\x1B[39m\x1B[32mf\x1B[39m\x1B[32mo\x1B[39m\x1B[32mo\x1B[39m\x1B[36m)\x1B[39m\x1B[32m.\x1B[39m\x1B[31m*\x1B[39m\x1B[35m\\b\x1B[39m\x1B[35m\\1\x1B[39m\x1B[35m\\b\x1B[39m\x1B[33m)\x1B[39m\x1B[35m.\x1B[39m\x1B[31m)\x1B[39m\x1B[35m*\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31ms\x1B[39m'],
+  [/^(?<sign>[-+])?(?:Infinity|NaN|\d+(?:\.\d+)?)(?=\s*$)/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33msign\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m-\x1B[39m\x1B[36m+\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[35m?\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36mI\x1B[39m\x1B[36mn\x1B[39m\x1B[36mf\x1B[39m\x1B[36mi\x1B[39m\x1B[36mn\x1B[39m\x1B[36mi\x1B[39m\x1B[36mt\x1B[39m\x1B[36my\x1B[39m\x1B[32m|\x1B[39m\x1B[36mN\x1B[39m\x1B[36ma\x1B[39m\x1B[36mN\x1B[39m\x1B[32m|\x1B[39m\x1B[36m\\d\x1B[39m\x1B[32m+\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m\\.\x1B[39m\x1B[35m\\d\x1B[39m\x1B[31m+\x1B[39m\x1B[33m)\x1B[39m\x1B[32m?\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[36m\\s\x1B[39m\x1B[32m*\x1B[39m\x1B[32m$\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?=.*\d)(?=.*[^\x61-\x7F])(?=.*[A-Za-z]).{8,}$/u, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[36m\\d\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m\\x61\x1B[39m\x1B[35m-\x1B[39m\x1B[36m\\x7F\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[36m.\x1B[39m\x1B[31m{\x1B[39m\x1B[36m8\x1B[39m\x1B[33m,\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [createRegExp('^\\p{Lu}\\p{Ll}+(?:\\s\\p{Lu}\\p{Ll}+)+$', 'u'), '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m\\p{\x1B[39m\x1B[33mLu\x1B[39m\x1B[31m}\x1B[39m\x1B[31m\\p{\x1B[39m\x1B[33mLl\x1B[39m\x1B[31m}\x1B[39m\x1B[35m+\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mLu\x1B[39m\x1B[33m}\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mLl\x1B[39m\x1B[33m}\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [createRegExp('^(?<emoji>\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F)+$', 'u'), '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33memoji\x1B[39m\x1B[31m>\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mEmoji_Presentation\x1B[39m\x1B[33m}\x1B[39m\x1B[32m|\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mEmoji\x1B[39m\x1B[33m}\x1B[39m\x1B[36m\\u\x1B[39m\x1B[36mF\x1B[39m\x1B[36mE\x1B[39m\x1B[36m0\x1B[39m\x1B[36mF\x1B[39m\x1B[31m)\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [createRegExp('^[\\p{Script=Greek}\\p{Nd}]+$', 'u'), '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m[\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mScript=Greek\x1B[39m\x1B[33m}\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mNd\x1B[39m\x1B[33m}\x1B[39m\x1B[31m]\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [createRegExp('^(?=.*\\p{Extended_Pictographic}).{1,140}$', 'su'), '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mExtended_Pictographic\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[36m.\x1B[39m\x1B[31m{\x1B[39m\x1B[36m1\x1B[39m\x1B[33m,\x1B[39m\x1B[36m140\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31msu\x1B[39m'],
+  [/^(?:\[(?:[^\]\\]|\.)*]|"(?:[^"\\]|\\.)*")$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\[\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[36m[\x1B[39m\x1B[35m^\x1B[39m\x1B[35m\\]\x1B[39m\x1B[35m\\\\\x1B[39m\x1B[36m]\x1B[39m\x1B[31m|\x1B[39m\x1B[35m\\.\x1B[39m\x1B[33m)\x1B[39m\x1B[32m*\x1B[39m\x1B[36m]\x1B[39m\x1B[32m|\x1B[39m\x1B[36m"\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[36m[\x1B[39m\x1B[35m^\x1B[39m\x1B[35m"\x1B[39m\x1B[35m\\\\\x1B[39m\x1B[36m]\x1B[39m\x1B[31m|\x1B[39m\x1B[35m\\\\\x1B[39m\x1B[32m.\x1B[39m\x1B[33m)\x1B[39m\x1B[32m*\x1B[39m\x1B[36m"\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<quote>["'])(?:\.|(?!\k<quote>)[\s\S])*\k<quote>$/, `\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mquote\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m"\x1B[39m\x1B[36m'\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\.\x1B[39m\x1B[32m|\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?!\x1B[39m\x1B[33m\\k<\x1B[39m\x1B[36mquote\x1B[39m\x1B[33m>\x1B[39m\x1B[33m)\x1B[39m\x1B[33m[\x1B[39m\x1B[36m\\s\x1B[39m\x1B[36m\\S\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[35m*\x1B[39m\x1B[32m\\k<\x1B[39m\x1B[31mquote\x1B[39m\x1B[32m>\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m`],
+  [/^(?:[A-Za-z_]\w*|\$[A-Za-z_]\w*)$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[36m_\x1B[39m\x1B[33m]\x1B[39m\x1B[36m\\w\x1B[39m\x1B[32m*\x1B[39m\x1B[32m|\x1B[39m\x1B[36m\\$\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mZ\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[36m_\x1B[39m\x1B[33m]\x1B[39m\x1B[36m\\w\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^((?:.\.\/)+)(?!\.)[A-Za-z0-9._/-]+$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[32m.\x1B[39m\x1B[35m\\.\x1B[39m\x1B[35m\\/\x1B[39m\x1B[33m)\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?!\x1B[39m\x1B[36m\\.\x1B[39m\x1B[31m)\x1B[39m\x1B[31m[\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mZ\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[33m0\x1B[39m\x1B[36m-\x1B[39m\x1B[33m9\x1B[39m\x1B[33m.\x1B[39m\x1B[33m_\x1B[39m\x1B[33m/\x1B[39m\x1B[33m-\x1B[39m\x1B[31m]\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?!.*\b(\w{3,})\b.*\b\1\b)[A-Za-z\s]+$/i, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?!\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[36m\\b\x1B[39m\x1B[33m(\x1B[39m\x1B[35m\\w\x1B[39m\x1B[36m{\x1B[39m\x1B[32m3\x1B[39m\x1B[35m,\x1B[39m\x1B[36m}\x1B[39m\x1B[33m)\x1B[39m\x1B[36m\\b\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[36m\\b\x1B[39m\x1B[36m\\1\x1B[39m\x1B[36m\\b\x1B[39m\x1B[31m)\x1B[39m\x1B[31m[\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mZ\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[33m\\s\x1B[39m\x1B[31m]\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mi\x1B[39m'],
+  [/^(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m[\x1B[39m\x1B[36mA\x1B[39m\x1B[35m-\x1B[39m\x1B[36mF\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mf\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[33m]\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[33m}\x1B[39m\x1B[36m:\x1B[39m\x1B[31m)\x1B[39m\x1B[31m{\x1B[39m\x1B[36m5\x1B[39m\x1B[31m}\x1B[39m\x1B[31m[\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mF\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mf\x1B[39m\x1B[33m0\x1B[39m\x1B[36m-\x1B[39m\x1B[33m9\x1B[39m\x1B[31m]\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^\[(?<ts>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z)\]\s(?<lvl>INFO|WARN|ERROR)\s(?<msg>.*)$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[33m\\[\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mts\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m4\x1B[39m\x1B[33m}\x1B[39m\x1B[36m-\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[33m}\x1B[39m\x1B[36m-\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[33m}\x1B[39m\x1B[36mT\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[33m}\x1B[39m\x1B[36m:\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[33m}\x1B[39m\x1B[36m:\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m2\x1B[39m\x1B[33m}\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m\\.\x1B[39m\x1B[35m\\d\x1B[39m\x1B[31m+\x1B[39m\x1B[33m)\x1B[39m\x1B[32m?\x1B[39m\x1B[36mZ\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\]\x1B[39m\x1B[33m\\s\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mlvl\x1B[39m\x1B[31m>\x1B[39m\x1B[36mI\x1B[39m\x1B[36mN\x1B[39m\x1B[36mF\x1B[39m\x1B[36mO\x1B[39m\x1B[32m|\x1B[39m\x1B[36mW\x1B[39m\x1B[36mA\x1B[39m\x1B[36mR\x1B[39m\x1B[36mN\x1B[39m\x1B[32m|\x1B[39m\x1B[36mE\x1B[39m\x1B[36mR\x1B[39m\x1B[36mR\x1B[39m\x1B[36mO\x1B[39m\x1B[36mR\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\s\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mmsg\x1B[39m\x1B[31m>\x1B[39m\x1B[35m.\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<lhs>\w+)\s*(?<op>\+=|-=|\*\*=|<<=)\s*(?<rhs>[^;]+);$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mlhs\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\w\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\s\x1B[39m\x1B[35m*\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mop\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\+\x1B[39m\x1B[36m=\x1B[39m\x1B[32m|\x1B[39m\x1B[36m-\x1B[39m\x1B[36m=\x1B[39m\x1B[32m|\x1B[39m\x1B[36m\\*\x1B[39m\x1B[36m\\*\x1B[39m\x1B[36m=\x1B[39m\x1B[32m|\x1B[39m\x1B[36m<\x1B[39m\x1B[36m<\x1B[39m\x1B[36m=\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\s\x1B[39m\x1B[35m*\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mrhs\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m;\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m;\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+  [/^(?<scheme>[a-z][a-z0-9+-.]*):(?<rest>\/\/[^?#\s]+(?:\?[^#\s]*)?(?:#[^\s]*)?|[^/\s][^\s]*)$/i, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mscheme\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[33m]\x1B[39m\x1B[33m[\x1B[39m\x1B[36ma\x1B[39m\x1B[35m-\x1B[39m\x1B[36mz\x1B[39m\x1B[36m0\x1B[39m\x1B[35m-\x1B[39m\x1B[36m9\x1B[39m\x1B[36m+\x1B[39m\x1B[35m-\x1B[39m\x1B[36m.\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[33m:\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mrest\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\/\x1B[39m\x1B[36m\\/\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m?\x1B[39m\x1B[36m#\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m\\?\x1B[39m\x1B[36m[\x1B[39m\x1B[35m^\x1B[39m\x1B[35m#\x1B[39m\x1B[35m\\s\x1B[39m\x1B[36m]\x1B[39m\x1B[31m*\x1B[39m\x1B[33m)\x1B[39m\x1B[32m?\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?:\x1B[39m\x1B[35m#\x1B[39m\x1B[36m[\x1B[39m\x1B[35m^\x1B[39m\x1B[35m\\s\x1B[39m\x1B[36m]\x1B[39m\x1B[31m*\x1B[39m\x1B[33m)\x1B[39m\x1B[32m?\x1B[39m\x1B[32m|\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m/\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[33m[\x1B[39m\x1B[36m^\x1B[39m\x1B[36m\\s\x1B[39m\x1B[33m]\x1B[39m\x1B[32m*\x1B[39m\x1B[31m)\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mi\x1B[39m'],
+  [createRegExp('^(?:[\\p{Letter}\\p{Mark}\\p{Number}._-]+)@(?:[\\p{Letter}\\p{Number}\\p{Mark}.-]+)\\.[\\p{Letter}]{2,}$', 'u'), '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m[\x1B[39m\x1B[36m\\p{\x1B[39m\x1B[35mLetter\x1B[39m\x1B[36m}\x1B[39m\x1B[36m\\p{\x1B[39m\x1B[35mMark\x1B[39m\x1B[36m}\x1B[39m\x1B[36m\\p{\x1B[39m\x1B[35mNumber\x1B[39m\x1B[36m}\x1B[39m\x1B[36m.\x1B[39m\x1B[36m_\x1B[39m\x1B[36m-\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m@\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[33m[\x1B[39m\x1B[36m\\p{\x1B[39m\x1B[35mLetter\x1B[39m\x1B[36m}\x1B[39m\x1B[36m\\p{\x1B[39m\x1B[35mNumber\x1B[39m\x1B[36m}\x1B[39m\x1B[36m\\p{\x1B[39m\x1B[35mMark\x1B[39m\x1B[36m}\x1B[39m\x1B[36m.\x1B[39m\x1B[36m-\x1B[39m\x1B[33m]\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\.\x1B[39m\x1B[31m[\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mLetter\x1B[39m\x1B[33m}\x1B[39m\x1B[31m]\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[33m,\x1B[39m\x1B[31m}\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [createRegExp('^[\\p{Alphabetic}&&\\p{ASCII}]+$', 'v'), '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[31m[\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mAlphabetic\x1B[39m\x1B[33m}\x1B[39m\x1B[33m&\x1B[39m\x1B[33m&\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[36mASCII\x1B[39m\x1B[33m}\x1B[39m\x1B[31m]\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m\x1B[31mv\x1B[39m'],
+  [/(a)/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?:a)/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?=a)/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?=\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?!a)/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?!\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?<=a)/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<=\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?<!a)/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<!\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?<name>a)/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mname\x1B[39m\x1B[31m>\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?<name>a)\k<name>/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mname\x1B[39m\x1B[31m>\x1B[39m\x1B[36ma\x1B[39m\x1B[31m)\x1B[39m\x1B[32m\\k<\x1B[39m\x1B[31mname\x1B[39m\x1B[32m>\x1B[39m\x1B[32m/\x1B[39m'],
+  [createRegExp('\\p{Letter}+', 'u'), '\x1B[32m/\x1B[39m\x1B[31m\\p{\x1B[39m\x1B[33mLetter\x1B[39m\x1B[31m}\x1B[39m\x1B[35m+\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [/[\u{1F600}-\u{1F601}]/u, '\x1B[32m/\x1B[39m\x1B[31m[\x1B[39m\x1B[33m\\u{\x1B[39m\x1B[36m1F600\x1B[39m\x1B[33m}\x1B[39m\x1B[36m-\x1B[39m\x1B[33m\\u{\x1B[39m\x1B[36m1F601\x1B[39m\x1B[33m}\x1B[39m\x1B[31m]\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [/\x61/, '\x1B[32m/\x1B[39m\x1B[33m\\x61\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\u{1F600}/u, '\x1B[32m/\x1B[39m\x1B[31m\\u{\x1B[39m\x1B[33m1F600\x1B[39m\x1B[31m}\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [/[a-z-]/, '\x1B[32m/\x1B[39m\x1B[31m[\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[33m-\x1B[39m\x1B[31m]\x1B[39m\x1B[32m/\x1B[39m'],
+  [/[a-z-]/, '\x1B[32m/\x1B[39m\x1B[31m[\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[33m-\x1B[39m\x1B[31m]\x1B[39m\x1B[32m/\x1B[39m'],
+  [/.{2,3}?abc?/, '\x1B[32m/\x1B[39m\x1B[36m.\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[33m,\x1B[39m\x1B[36m3\x1B[39m\x1B[31m}\x1B[39m\x1B[35m?\x1B[39m\x1B[33ma\x1B[39m\x1B[33mb\x1B[39m\x1B[33mc\x1B[39m\x1B[35m?\x1B[39m\x1B[32m/\x1B[39m'],
+  [/a{2}/, '\x1B[32m/\x1B[39m\x1B[33ma\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[31m}\x1B[39m\x1B[32m/\x1B[39m'],
+  [/\d/, '\x1B[32m/\x1B[39m\x1B[33m\\d\x1B[39m\x1B[32m/\x1B[39m'],
+  [/[^a-z\d\u{1F600}-\u{1F601}]/u, '\x1B[32m/\x1B[39m\x1B[31m[\x1B[39m\x1B[33m^\x1B[39m\x1B[33ma\x1B[39m\x1B[36m-\x1B[39m\x1B[33mz\x1B[39m\x1B[33m\\d\x1B[39m\x1B[33m\\u{\x1B[39m\x1B[36m1F600\x1B[39m\x1B[33m}\x1B[39m\x1B[36m-\x1B[39m\x1B[33m\\u{\x1B[39m\x1B[36m1F601\x1B[39m\x1B[33m}\x1B[39m\x1B[31m]\x1B[39m\x1B[32m/\x1B[39m\x1B[31mu\x1B[39m'],
+  [/(?<year>\d{4})-\d{2}|\d{2}-(?<year>\d{4})/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33myear\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m4\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[33m-\x1B[39m\x1B[33m\\d\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[31m}\x1B[39m\x1B[35m|\x1B[39m\x1B[33m\\d\x1B[39m\x1B[31m{\x1B[39m\x1B[36m2\x1B[39m\x1B[31m}\x1B[39m\x1B[33m-\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33myear\x1B[39m\x1B[31m>\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[35m4\x1B[39m\x1B[33m}\x1B[39m\x1B[31m)\x1B[39m\x1B[32m/\x1B[39m'],
+  [/(?<=Mr\.|Mrs.)\s[A-Z]\w+/, '\x1B[32m/\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<=\x1B[39m\x1B[36mM\x1B[39m\x1B[36mr\x1B[39m\x1B[36m\\.\x1B[39m\x1B[32m|\x1B[39m\x1B[36mM\x1B[39m\x1B[36mr\x1B[39m\x1B[36ms\x1B[39m\x1B[35m.\x1B[39m\x1B[31m)\x1B[39m\x1B[33m\\s\x1B[39m\x1B[31m[\x1B[39m\x1B[33mA\x1B[39m\x1B[36m-\x1B[39m\x1B[33mZ\x1B[39m\x1B[31m]\x1B[39m\x1B[33m\\w\x1B[39m\x1B[35m+\x1B[39m\x1B[32m/\x1B[39m'],
+  [/a/giu, '\x1B[32m/\x1B[39m\x1B[33ma\x1B[39m\x1B[32m/\x1B[39m\x1B[31mgiu\x1B[39m'],
+  [/\p{Let(?<quote>["'])(?:\.|(?!\k<quote>)[\s\S])*\k<quote>$/, `\x1B[32m/\x1B[39m\x1B[33m\\p{\x1B[39m\x1B[33mL\x1B[39m\x1B[33me\x1B[39m\x1B[33mt\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?<\x1B[39m\x1B[33mquote\x1B[39m\x1B[31m>\x1B[39m\x1B[33m[\x1B[39m\x1B[36m"\x1B[39m\x1B[36m'\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36m\\.\x1B[39m\x1B[32m|\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?!\x1B[39m\x1B[33m\\k<\x1B[39m\x1B[36mquote\x1B[39m\x1B[33m>\x1B[39m\x1B[33m)\x1B[39m\x1B[33m[\x1B[39m\x1B[36m\\s\x1B[39m\x1B[36m\\S\x1B[39m\x1B[33m]\x1B[39m\x1B[31m)\x1B[39m\x1B[35m*\x1B[39m\x1B[32m\\k<\x1B[39m\x1B[31mquote\x1B[39m\x1B[32m>\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m`],
+  [/^p{Lu}p{Ll}+(?:sp{Lu}p{Ll}+)+$/, '\x1B[32m/\x1B[39m\x1B[35m^\x1B[39m\x1B[33mp\x1B[39m\x1B[33m{\x1B[39m\x1B[33mL\x1B[39m\x1B[33mu\x1B[39m\x1B[33m}\x1B[39m\x1B[33mp\x1B[39m\x1B[33m{\x1B[39m\x1B[33mL\x1B[39m\x1B[33ml\x1B[39m\x1B[33m}\x1B[39m\x1B[35m+\x1B[39m\x1B[31m(\x1B[39m\x1B[31m?:\x1B[39m\x1B[36ms\x1B[39m\x1B[36mp\x1B[39m\x1B[36m{\x1B[39m\x1B[36mL\x1B[39m\x1B[36mu\x1B[39m\x1B[36m}\x1B[39m\x1B[36mp\x1B[39m\x1B[36m{\x1B[39m\x1B[36mL\x1B[39m\x1B[36ml\x1B[39m\x1B[36m}\x1B[39m\x1B[32m+\x1B[39m\x1B[31m)\x1B[39m\x1B[35m+\x1B[39m\x1B[35m$\x1B[39m\x1B[32m/\x1B[39m'],
+];
+
+for (const test of tests) {
+  expectColored(test);
+}
+
+// These test cases do not highlight the regular expression correctly.
+const brokenTests = [
+  [/\p{Let(?<quote>["'])(?:\.|\p{quote}[\s\S])*\k<quote>$/, `\x1B[32m/\x1B[39m\x1B[31m\\p{\x1B[39m\x1B[33mLet(?<quote>["'])(?:\\.|\\p{quote\x1B[39m\x1B[31m}\x1B[39m\x1B[31m[\x1B[39m\x1B[33m\\s\x1B[39m\x1B[33m\\S\x1B[39m\x1B[31m]\x1B[39m\x1B[32m)\x1B[39m\x1B[36m*\x1B[39m\x1B[32m\\k<\x1B[39m\x1B[32mquote\x1B[39m\x1B[32m>\x1B[39m\x1B[36m$\x1B[39m\x1B[32m/\x1B[39m`],
+];
+
+for (const test of brokenTests) {
+  expectColored(test);
+}
+
+{
+  const regexp = /(?<year>\d{4})-\d{2}|\d{2}-(?<year>\d{4})/;
+  const regular = util.inspect(regexp, { colors: true });
+
+  util.inspect.styles.regexp.colors = [];
+  const emptyColorArray = util.inspect(regexp, { colors: true });
+
+  assert.strictEqual(emptyColorArray, regular);
+
+  util.inspect.styles.regexp.colors = undefined;
+  const undefinedColors = util.inspect(regexp, { colors: true });
+
+  assert.strictEqual(undefinedColors, regular);
+
+  util.inspect.styles.regexp.colors = ['red', 'yellow', 'cyan'];
+  const customColors = util.inspect(regexp, { colors: true });
+
+  assert.strictEqual(
+    customColors,
+    '\x1B[31m/\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?<\x1B[39m\x1B[36myear\x1B[39m\x1B[33m>\x1B[39m\x1B[31m\\d\x1B[39m\x1B[36m{\x1B[39m\x1B[33m4\x1B[39m\x1B[36m}\x1B[39m\x1B[33m)\x1B[39m\x1B[36m-\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[31m2\x1B[39m\x1B[33m}\x1B[39m\x1B[33m|\x1B[39m\x1B[36m\\d\x1B[39m\x1B[33m{\x1B[39m\x1B[31m2\x1B[39m\x1B[33m}\x1B[39m\x1B[36m-\x1B[39m\x1B[33m(\x1B[39m\x1B[33m?<\x1B[39m\x1B[36myear\x1B[39m\x1B[33m>\x1B[39m\x1B[31m\\d\x1B[39m\x1B[36m{\x1B[39m\x1B[33m4\x1B[39m\x1B[36m}\x1B[39m\x1B[33m)\x1B[39m\x1B[31m/\x1B[39m'
+  );
+
+  util.inspect.styles.regexp = 'red';
+  const redStyle = util.inspect(regexp, { colors: true });
+
+  assert.strictEqual(redStyle, '\x1B[31m/(?<year>\\d{4})-\\d{2}|\\d{2}-(?<year>\\d{4})/\x1B[39m');
+}

filename: test/parallel/test-util-inspect.js
patch: @@ -922,7 +922,7 @@ assert.strictEqual(util.inspect({ __proto__: Date.prototype }), 'Date {}');
   testColorStyle('null', null);
   testColorStyle('string', 'test string');
   testColorStyle('date', new Date());
-  testColorStyle('regexp', /regexp/);
+  // RegExp now uses token-level highlighting; verified in a dedicated test file.
 }
 
 // An object with "hasOwnProperty" overwritten should not throw.

filename: test/sequential/test-util-debug.js
patch: @@ -73,9 +73,8 @@ function test(environ, shouldWrite, section, forceColors = false) {
       const addCodes = (arr) => [`\x1B[${arr[0]}m`, `\x1B[${arr[1]}m`];
       const num = addCodes(colors[styles.number]);
       const str = addCodes(colors[styles.string]);
-      const regexp = addCodes(colors[styles.regexp]);
       const start = `${section.toUpperCase()} ${num[0]}${child.pid}${num[1]}`;
-      const debugging = `${regexp[0]}/debugging/${regexp[1]}`;
+      const debugging = styles.regexp('/debugging/');
       expectErr =
         `${start}: this { is: ${str[0]}'a'${str[1]} } ${debugging}\n` +
         `${start}: num=1 str=a obj={"foo":"bar"}\n`;