I-Regexp: An Interoperable Regular Expression Format
Extracted elements (24)
Character class subtraction was omitted from I-Regexp because, although useful in XSD, it is absent from most parsing-regexp dialects and would prevent straightforward mapping.
I-Regexp intentionally supports only Boolean matching (not capture groups, lookahead, or backreferences) because parsing-regexp libraries accumulating these features have become susceptible to exploitable bugs and unpredictable performance leading to denial-of-service attacks.
I-Regexp was motivated by the JSONPath WG's need for a regexp mechanism interoperable across popular libraries. No suitable specification existed, so a new limited flavor was defined, inspired by the I-JSON approach of selecting a safe, interoperable subset.
Multi-character escapes (\d, \w, \s and their complements) were omitted because they exhibit large variation between regexp flavors, making interoperability impossible without them.
Unicode category escapes (\p{}/\P{}) were retained despite the challenge they pose for constrained environments because they are widely available in modern regexp libraries, and translating them to character-class matches would itself require access to the same Unicode tables.
Any I-Regexp is also a valid XSD regexp; the mapping is the identity function. XSD 1.0 implementations incorporating errata are considered equivalent to XSD 1.1 for the purposes of this specification.
For PCRE, RE2, and Ruby, perform the same dot substitution as for ECMAScript but enclose with \A(?: and )\z instead of ^(?: and )$.
I-Regexp is defined as a subset of XSD regexp (XSD 1.0/1.1 Part 2), explicitly excluding character class subtraction, multi-character escapes (\s, \S, \w, etc.), and Unicode block references.
Multi-character escapes unsupported in I-Regexp have direct substitutes: \S → [^ \t\n\r], \d → [0-9], and \p{IsBasicLatin} → [\u0000-\u007f]. Note that XSD's \d means \p{Nd} (all Unicode digits), not just [0-9].
To use an I-Regexp as an ECMAScript regexp, replace any unescaped dot outside character classes with [^\n\r], then enclose the result in ^(?: and )$, and interpret as a Unicode pattern (the 'u' flag).
An I-Regexp implementation MUST be a complete implementation of the defined subset; in particular, full support for the Unicode functionality defined in the specification is REQUIRED.
An I-Regexp implementation MUST NOT limit itself to 7- or 8-bit character sets such as ASCII.
An I-Regexp implementation MUST support the Unicode character property set in character classes (i.e., \p{} and \P{} category escapes).
An I-Regexp MUST conform to the ABNF specification given in Figure 1 of the document, which defines the complete grammar for i-regexp, branch, piece, atom, quantifier, charClass, and related productions.
charClassExpr is not allowed to match the pattern [^]; although the grammar would parse it as a positive character class containing the single character '^', it is explicitly prohibited as an additional restriction.
Checking implementations — those that verify regexp compliance with the specification — are RECOMMENDED so that users have confidence they did not accidentally insert non-interoperable syntax. Low-effort implementations that simply map to another library via the Section 5 steps are excepted.
Implementations SHOULD document whether or not they are checking implementations.
Implementations that interpret I-Regexps MUST yield Boolean results as specified in XSD Part 2: Datatypes [XSD-2].
I-Regexp syntax is defined by an ABNF grammar covering alternation (branch separated by '|'), quantifiers ('*', '+', '?', range-quantifier '{m,n}'), atoms (NormalChar, charClass, grouped i-regexp), character classes (dot, SingleCharEsc, charClassEsc, charClassExpr), and Unicode category escapes (\p{} and \P{}).
More complex regexp libraries may contain exploitable bugs leading to crashes and remote code execution. Implementations using such libraries should check vendor documentation for configurable mitigations and resource-consumption limits.
Non-checking implementations that delegate to an underlying regexp engine expose that engine's security limitations. A checking implementation is still RECOMMENDED even when an engine with built-in security measures (e.g., RE2) is used.
Range quantifiers (e.g., a{2,4}) pose particular challenges; implementations may limit composability (disallowing nested range quantifiers) or range magnitude (disallowing very large bounds such as a{20,200000}), or detect and reject excessive resource consumption they cause.
Regexp engines often exhibit hard-to-predict performance, enabling denial-of-service attacks via attacker-controlled expressions. I-Regexp is designed to allow implementations that run in linear time and space in the input, and that detect when this cannot be guaranteed.
UTF-8 security considerations from RFC 3629 Section 10 apply to I-Regexp implementations; in particular, implementations may need to mitigate platform limitations regarding invalid UTF-8 sequences, as described in RFC 3629 Section 3.