Convenient Regular Expressions
improve
organize
maintain
review
express in words
reuse
improve
your RegExp.
▶  Try it
// Match JS floating point number
Classic
const number = /[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/gsu
Convenient Regular Expressions
const number = cre.global`
    optional [+-];                    // Sign
    {
        at-least-1 digit;             // Integral part
        optional (".", repeat digit); // Optional factional part
    } or {
        ".";
        at-least-1 digit;             // Variant with only fractional part
    }
    optional {                        // Optional exponent part
        [eE];
        optional [+-];
        at-least-1 digit;
    }
`;
▶  Try it
// Match JSON array of numbers
Classic
const arrayOfNumbers = /^\s*\[\s*(?:(?:-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[e↩
E][+-]?\d+)?\s*,\s*)*-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?\s*)?\↩
]\s*$/su
Convenient Regular Expressions
const number = cre`
    optional "-";               // Sign
    {                           // Integral part
        "0";                    // Zero is special case
    } or {
        [1-9], repeat digit;    // Everything above zero
    }
    optional {                  // Optional factional part
        ".";
        at-least-1 digit;
    }
    optional {                  // Optional exponent part
        [eE];
        optional [+-];
        at-least-1 digit;
    }
`;

const ws = cre`repeat whitespace`;

const arrayOfNumbers = cre`
    begin-of-text, ${ws};      // Trim leading whitespaces
    "[", ${ws};                // Begin of array
    optional {                 // Optional, because array can be empty
        repeat {               // Numbers with trailing comma
            ${number}, ${ws};
            ",", ${ws};
        }
        ${number}, ${ws};      // Last number has no comma
    }
    "]", ${ws};                // End of array
    end-of-text;
`;
▶  Try it
// Match IPv4 address
Classic
const ipv4address = /(?<!\d|\.)(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?↩
\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}(?!\d|\.)/gsu
Convenient Regular Expressions
const ipv4number = cre`
    {
        "25", [0-5];           // Range 250…255
    } or {
        "2", [0-4], digit;     // Range 240…249
    } or {
        "1", digit, digit;     // Range 100…199
    } or {
        optional [1-9], digit; // Range 0…99
    }
`;

const ipv4address = cre.global`
    // Disallow anything behind that reassembles IPv4 addresses
    lookbehind not (digit or ".");
    // Four numbers separated by dot
    ${ipv4number};
    3-times {
        ".";
        ${ipv4number};
    }
    // Disallow anything ahead that reassembles IPv4 addresses
    lookahead not (digit or ".");
`;
▶  Try it
// Match time in both 12 and 24-hour format
Classic
const time = /(?:1[0-2]|0?\d):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?\s*(?:AM|PM)|(?:2↩
[0-3]|[01]?\d):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?/gisu
Convenient Regular Expressions
const minutesAndSoOn = cre.ignoreCase`
    ":", [0-5], digit;                    // Minutes
    optional {
        ":", [0-5], digit;                // Seconds
        optional (".", at-least-1 digit); // Fraction of a second
    }
`;

const time = cre.global.ignoreCase`
    {
        // 12-hour format
        {
            "1", [0-2];                 // Range 10…12
        } or {
            optional "0", digit;        // Range 0…9
        }
        ${minutesAndSoOn};
        repeat whitespace;              // Allow any whitespaces before AM/PM
        "AM" or "PM";
    } or {
        // 24-hour format
        {
            "2", [0-3];                 // Range 20…23
        } or {
            optional [01], digit;       // Range 0…19
        }
        ${minutesAndSoOn};
    }
`;
What are Convenient Regular Expressions?
Regular expression syntax redefined

The "Convenient Regular Expressions" give an alternative syntax for regular expressions. The main goal is to introduce a syntax that is easily manageable in complex regular expressions.

Under the hood

The module is still using a standard JavaScript's RegExp object. Essentially, it is a runtime transpiler that converts "Convenient Regular Expression" into a classic regular expression.

Why Convenient Regular Expressions?
You can use whitespaces

Organize your expression structure with spaces, new lines, and indentation.

You can use comments

A good comment can clarify an expression a lot making it easier to understand later.

You are using words

The words are significantly more readable than some arbitrarily selected special characters.

Maintenance is simpler

If you want to make a change in a well-structured expression, you simply do it. With complex classic regular expressions, first, you have to parse it in your head, track brackets, and groups, and divide it into pieces.

Code review is faster and more accurate

It is easier to understand well-structured expressions and changes in such expressions. Have you ever tried to review changes in regular expressions that are longer than 100 characters?

You can reuse the expressions

You can put pieces of your expression into variables and reuse them multiple times later. It is like splitting your code into functions.

You are using sane syntax

Long and complex regular expressions look like some esoteric programming languages created just to make the code unreadable.

Get started
Install
npm install con-reg-exp

Or, if you prefer to download and use in an HTML tag:

<script src="con-reg-exp.min.js"></script>
Import module
import cre from "con-reg-exp";

Or, if you are using CommonJS:

const cre = require("con-reg-exp");

If you are using an HTML tag, the cre symbol is globally available and you don't need to import anything.

Write your first Convenient Regular Expression
const inputText = "Hello World!!!";

const pattern = cre.global`
    at-least-1 word-char
`;

const words = inputText.match(pattern);

console.log(words);