Skip to content

Latest commit

 

History

History
112 lines (63 loc) · 4.06 KB

File metadata and controls

112 lines (63 loc) · 4.06 KB

Commonly Used REGular EXpressions

Note

Some regular expressions here are vulnerable to ReDOS attack. Be sure to use them with following conditions:

  • server side: Run these expression with libraries such as google/re2, node-re2.
  • client side: avoid them, or at least impose necessary limitations on input.

Installation

npm install --save curegex

Usage

include curegex.js or curegex.tw.js, then use:

curegex.get("email").exec(mystring);
curegex.get("email", re2).exec(mystring); /* use `re2` regex engine instead of native RegExp */

set default regular expression engine:

curegex.engine(re2);

Usage with NodeJS

include curegex and use it by scope:

var curegex = require("curegex");
var curegextw = require("curegex").tw;

Switching Regex Engines

curegex.get(name, engine) accepts any RegExp-like constructor. Three engines are known to work:

native RegExp ( default )

curegex.get("email").exec(mystring);

fast and dependency-free, but vulnerable to ReDoS for some patterns. see Note above.

re2 ( native binding of google/re2 )

var re2 = require("re2");
curegex.tw.get("email", re2).exec(mystring);

linear-time matching ( ReDoS-safe ). note that re2 is a native module:

  • it needs compilation toolchain / prebuilt binaries on install.
  • re2 >= 1.26 requires Node ^22.22.2 || ^24.15.0 || >=26.

re2js ( pure JavaScript port of RE2 )

var curegex = require("curegex");
var { RE2JS } = require("re2js");
curegex.tw.get("email", RE2JS).exec(mystring);

also linear-time ( ReDoS-safe ), no native compilation, works with any Node version and in browsers. curegex does not depend on re2js — install it yourself and pass the RE2JS class in; curegex detects it ( a class with static compile and flag constants, not a new-able RegExp-like constructor ) and wraps it into a RegExp-like engine automatically. the wrapper is also available explicitly:

var engine = curegex.adapters.re2js(RE2JS);
curegex.tw.get("email", engine).exec(mystring);

to switch between re2 and re2js, only the engine argument changes:

var engine = process.env.USE_RE2JS ? require("re2js").RE2JS : require("re2");
curegex.tw.get("email", engine).exec(mystring);

or set it once as default:

curegex.engine(engine);     /* for curegex.get(...) */
curegex.tw.engine(engine);  /* for curegex.tw.get(...) */

the effective engine is exposed as curegex.re ( and curegex.tw.re ) — always a new-able, RegExp-like constructor, so ad-hoc patterns can follow the same engine setting:

curegex.engine(RE2JS);
new curegex.re("^some-pattern$", "i").exec(mystring);
/* curegex.re is native RegExp when no engine is set */

engine compatibility caveats

  • password-len8-* rules use lookahead (?=...), which RE2-based engines ( both re2 and re2js ) do not support — get() throws with these engines. use native RegExp for them.
  • rules are maintained in engine-neutral syntax ( e.g., literal char ranges instead of \u escapes, which re2js rejects ). npm test verifies every rule against all three engines.
  • the re2js wrapper is RegExp-like, not a RegExp: exec() / test() work ( non-string input is String()-coerced like native RegExp ), but there is no source / flags / lastIndex, and it cannot be passed to String.prototype.match / replace.
  • in exec() results, unmatched capture groups are null with re2js but undefined with RegExp / re2 ( truthiness is the same ).

Test

npm test

runs all rules against native RegExp, re2 and re2js, and checks the three engines agree.

Resources

License

MIT