re2 0.5.0 copy "re2: ^0.5.0" to clipboard
re2: ^0.5.0 copied to clipboard

Linear-time regular expressions for Dart via Google's RE2 over FFI. Immune to catastrophic backtracking (ReDoS).

example/re2_example.dart

import 'package:re2/re2.dart';

// A common job: sanitize text you did not write, such as a log line or a
// user-submitted message, before you store or forward it. The pattern and the
// input are both untrusted, which is exactly where dart:core's backtracking
// RegExp can be made to hang. RE2 matches and substitutes in linear time, so
// the same work stays fast and safe.
void main() {
  // 1) Redact emails and long digit runs (card-like numbers) from a log line.
  final email = Re2(r'[\w.+-]+@[\w.-]+');
  final digits = Re2(r'\d{12,}');
  try {
    const line =
        'user bob@example.com paid with 4111111111111111 at checkout';
    // replaceAll rewrites every match; the rewrite can reference groups with
    // \1..\9, but here a fixed mask is enough.
    final noEmail = email.replaceAll(line, '<email>');
    final safe = digits.replaceAll(noEmail, '<redacted>');
    print(safe); // user <email> paid with <redacted> at checkout
  } finally {
    email.dispose();
    digits.dispose();
  }

  // 2) Keep part of a match with a group reference: mask the local part of an
  // address but keep the domain, so aggregate stats by domain still work.
  final address = Re2(r'([\w.+-]+)@([\w.-]+)');
  try {
    print(address.replaceAll('a@example.com, b@dartlang.org', r'***@\2'));
    // ***@example.com, ***@dartlang.org

    for (final match in address.allMatches('reach bob@example.com today')) {
      print('${match.group(1)} at ${match.group(2)}'); // bob at example.com
    }
  } finally {
    address.dispose();
  }

  // 3) The reason to use RE2 here: a pattern that needs backreferences or
  // lookaround is rejected at construction, so you find out before running it
  // on untrusted input, not during a hang.
  try {
    Re2(r'(\w+)\1'); // backreference
  } on FormatException catch (e) {
    print('rejected unsupported pattern: ${e.message}');
  }

  // 4) A Re2 is a Pattern, so it drops straight into the String API in place of
  // a RegExp, and those calls then run in RE2's linear time.
  final comma = Re2(r'\s*,\s*');
  try {
    print('a, b ,c,  d'.split(comma)); // [a, b, c, d]
    print('123abc'.startsWith(comma)); // false
  } finally {
    comma.dispose();
  }
}
0
likes
160
points
79
downloads
screenshot

Documentation

API reference

Publisher

verified publisherdeveloperyusuf.com

Weekly Downloads

Linear-time regular expressions for Dart via Google's RE2 over FFI. Immune to catastrophic backtracking (ReDoS).

Repository (GitHub)
View/report issues

Topics

#regex #re2 #security #ffi #performance

License

MIT (license)

Dependencies

code_assets, ffi, hooks, native_toolchain_c

More

Packages that depend on re2