Skip to content
Eugene Lazutkin edited this page Nov 8, 2026 · 1 revision

Edge cases

RE2 follows the built-in RegExp in ordinary use. This page lists limits and differences you rarely meet. For the common ones, such as the missing backreferences and lookahead assertions, see Limitations in the README.

Result size of replace()

replace() throws a RangeError when its result is too long:

  • A string result can't exceed V8's maximum string length, counted in UTF-8 bytes.
  • A binary result can't exceed the larger of that length and twice the size of the input.

The check runs before the result is allocated, so a template that amplifies its input fails quickly:

const RE2 = require('re2');

try {
  'a'.repeat(40000).replace(new RE2('a', 'g'), "$'");
} catch (error) {
  console.log(error instanceof RangeError); // true
}

The built-in engine counts UTF-16 code units, so multi-byte text reaches this limit sooner in RE2. For example, 'é'.repeat(31000).replace(pattern, "$'") makes a string of about 480 million code units. The built-in engine returns it, and RE2 throws because the result takes about 961 million bytes as UTF-8.

\B in RE2.Set

A set search reports which patterns matched but not where. In the default 'unanchored' mode, a \B in a pattern can match between the bytes of a multi-byte character:

const RE2 = require('re2');

new RE2.Set(['\\B']).test('b中c'); // true
new RE2('\\B').test('b中c'); // false
/\B/u.test('b中c'); // false

To test such a pattern, use an individual RE2 object.

Clone this wiki locally