{"id":13527225,"url":"https://github.com/le0pard/re2js","last_synced_at":"2026-04-12T00:16:48.134Z","repository":{"id":181246919,"uuid":"658017011","full_name":"le0pard/re2js","owner":"le0pard","description":"RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching","archived":false,"fork":false,"pushed_at":"2026-03-31T22:22:23.000Z","size":11129,"stargazers_count":172,"open_issues_count":1,"forks_count":7,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-01T01:23:11.071Z","etag":null,"topics":["javascript","js","re2","regex","regex-engine","regexp"],"latest_commit_sha":null,"homepage":"https://re2js.leopard.in.ua/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/le0pard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://www.buymeacoffee.com/leopard"]}},"created_at":"2023-06-24T14:04:44.000Z","updated_at":"2026-03-29T07:29:16.000Z","dependencies_parsed_at":"2023-07-14T16:58:54.012Z","dependency_job_id":"f26a9c24-733f-42ce-892a-acade716078d","html_url":"https://github.com/le0pard/re2js","commit_stats":null,"previous_names":["le0pard/re2js"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/le0pard/re2js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/le0pard%2Fre2js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/le0pard%2Fre2js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/le0pard%2Fre2js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/le0pard%2Fre2js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/le0pard","download_url":"https://codeload.github.com/le0pard/re2js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/le0pard%2Fre2js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31530647,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","js","re2","regex","regex-engine","regexp"],"created_at":"2024-08-01T06:01:43.562Z","updated_at":"2026-04-07T22:01:45.502Z","avatar_url":"https://github.com/le0pard.png","language":"JavaScript","readme":"# RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching\n[![Test/Build/Publish](https://github.com/le0pard/re2js/actions/workflows/ci.yml/badge.svg)](https://github.com/le0pard/re2js/actions/workflows/ci.yml)\n\n## [Playground](https://re2js.leopard.in.ua/)\n\n## TLDR\n\nThe built-in JavaScript regular expression engine can, under certain special combinations, run in exponential time. This situation can trigger what's referred to as a [Regular Expression Denial of Service (ReDoS)](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). RE2, a different regular expression engine, can effectively safeguard your Node.js applications from ReDoS attacks. With RE2JS, this protective feature extends to browser environments as well, enabling you to utilize the RE2 engine more comprehensively.\n\n## What is RE2?\n\nRE2 is a regular expression engine designed to operate in time proportional to the size of the input, ensuring linear time complexity. RE2JS, on the other hand, is a pure JavaScript port of the [RE2 library](https://github.com/google/re2) — more specifically, it's a port of the [RE2/J library](https://github.com/google/re2j).\n\nJavaScript standard regular expression package, [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions), and many other widely used regular expression packages such as PCRE, Perl and Python use a backtracking implementation strategy: when a pattern presents two alternatives such as a|b, the engine will try to match subpattern a first, and if that yields no match, it will reset the input stream and try to match b instead.\n\nIf such choices are deeply nested, this strategy requires an exponential number of passes over the input data before it can detect whether the input matches. If the input is large, it is easy to construct a pattern whose running time would exceed the lifetime of the universe. This creates a security risk when accepting regular expression patterns from untrusted sources, such as users of a web application.\n\nIn contrast, the RE2 algorithm explores all matches simultaneously in a single pass over the input data by using a nondeterministic finite automaton.\n\nThere are certain features of PCRE or Perl regular expressions that cannot be implemented in linear time, for example, backreferences, but the vast majority of regular expressions patterns in practice avoid such features.\n\n## Installation\n\nTo install RE2JS:\n\n```bash\n# npm\nnpm install re2js\n# yarn\nyarn add re2js\n# pnpm\npnpm add re2js\n# bun\nbun add re2js\n```\n\n## Usage\n\nThis document provides a series of examples demonstrating how to use RE2JS in your code. For more detailed information about regex syntax, please visit this page: [Google RE2 Syntax Documentation](https://github.com/google/re2/wiki/Syntax).\n\nYou can utilize ECMAScript (ES6) imports to import and use the RE2JS library:\n\n```js\nimport { RE2JS } from 're2js'\n```\n\nIf you're using CommonJS, you can `require` the library:\n\n```js\nconst { RE2JS } = require('re2js')\n```\n\n### Compiling Patterns\n\nYou can compile a regex pattern using the `compile()` function:\n\n```js\nimport { RE2JS } from 're2js'\n\nconst p = RE2JS.compile('abc');\nconsole.log(p.pattern()); // Outputs: 'abc'\nconsole.log(p.flags()); // Outputs: 0\n```\n\nThe `compile()` function also supports flags:\n\n```js\nimport { RE2JS } from 're2js'\n\nconst p = RE2JS.compile('abc', RE2JS.CASE_INSENSITIVE | RE2JS.MULTILINE);\nconsole.log(p.pattern()); // Outputs: 'abc'\nconsole.log(p.flags()); // Outputs: 5\n```\n\nSupported flags:\n\n```js\n/**\n * Flag: case insensitive matching.\n */\nRE2JS.CASE_INSENSITIVE\n/**\n * Flag: dot ({@code .}) matches all characters, including newline.\n */\nRE2JS.DOTALL\n/**\n * Flag: multiline matching: {@code ^} and {@code $} match at beginning and end of line, not just\n * beginning and end of input.\n */\nRE2JS.MULTILINE\n/**\n * Flag: Unicode groups (e.g. {@code \\p\\ Greek\\} ) will be syntax errors.\n */\nRE2JS.DISABLE_UNICODE_GROUPS\n/**\n * Flag: matches longest possible string (changes the match semantics to leftmost-longest).\n */\nRE2JS.LONGEST_MATCH\n```\n\n### Checking for Matches\n\nRE2JS allows you to check if a string matches a given regex pattern using the `matches()` function.\n\n***Performance Note:** The `matches()` method is highly optimized. It performs a strict anchored check and runs directly on the high-speed DFA (Deterministic Finite Automaton) engine without tracking capture groups or instantiating a stateful `Matcher` object.*\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.matches('ab+c', 'abbbc') // true\nRE2JS.matches('ab+c', 'cbbba') // false\n// or\nRE2JS.compile('ab+c').matches('abbbc') // true\nRE2JS.compile('ab+c').matches('cbbba') // false\n// with flags\nRE2JS.compile('ab+c', RE2JS.CASE_INSENSITIVE).matches('AbBBc') // true\nRE2JS.compile(\n  '^ab.*c$',\n  RE2JS.DOTALL | RE2JS.MULTILINE | RE2JS.CASE_INSENSITIVE\n).matches('AB\\nc') // true\n```\n\n### Finding Matches\n\nTo find a match for a given regex pattern in a string, you can use the `find()` function\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('ab+c').matcher('xxabbbc').find() // true\nRE2JS.compile('ab+c').matcher('cbbba').find() // false\n// with flags\nRE2JS.compile('ab+c', RE2JS.CASE_INSENSITIVE).matcher('abBBc').find() // true\n```\n\nExample to collect all matches in string\n\n```js\nimport { RE2JS } from 're2js'\n\nconst p = RE2JS.compile('abc+')\nconst matchString = p.matcher('abc abcccc abcc')\nconst results = []\nwhile (matchString.find()) {\n  results.push(matchString.group())\n}\nresults // ['abc', 'abcccc', 'abcc']\n```\n\nThe `find()` method searches for a pattern match in a string starting from a specific index\n\n```js\nimport { RE2JS } from 're2js'\n\nconst p = RE2JS.compile('.*[aeiou]')\nconst matchString = p.matcher('abcdefgh')\nmatchString.find(0) // true\nmatchString.group() // 'abcde'\nmatchString.find(1) // true\nmatchString.group() // 'bcde'\nmatchString.find(4) // true\nmatchString.group() // 'e'\nmatchString.find(7) // false\n```\n\n### High-Performance Boolean Testing\n\nIf you only need to know **whether** a string matches a pattern (without extracting capture groups), you should use the `test()`, `testExact()`, or `matches()` methods. Unlike `.matcher()`, these methods do not instantiate stateful `Matcher` objects and request exactly `0` capture groups. This guarantees that execution is securely routed to the high-speed DFA (Deterministic Finite Automaton) engine whenever possible in linear `O(n)` time\n\n#### `test(input)`\n\nTests if the regular expression matches **any part** of the provided input (unanchored). This method mirrors the standard JavaScript `RegExp.prototype.test()` API\n\n```js\nimport { RE2JS } from 're2js';\n\n// Compile once, reuse often\nconst re = RE2JS.compile('error|warning|critical');\n\n// Extremely fast, unanchored DFA search\nif (re.test('The system encountered a critical failure')) {\n  console.log('Log needs attention!');\n}\n```\n\n#### `testExact(input)`\n\nTests if the regular expression matches the entire input string (anchored to both start and end).\n\n*Note: `RE2JS.matches()` delegates to this method, so they provide the exact same performance and behavior.*\n\n```js\nimport { RE2JS } from 're2js';\n\nconst isHex = RE2JS.compile('[0-9A-Fa-f]+');\n\n// Fast, anchored DFA validation\nconsole.log(isHex.testExact('1A4F'));      // true\nconsole.log(isHex.testExact('1A4F-xyz'));  // false\n```\n\n### Checking Initial Match\n\nThe `lookingAt()` method determines whether the start of the given string matches the pattern\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('abc').matcher('abcdef').lookingAt() // true\nRE2JS.compile('abc').matcher('ab').lookingAt() // false\n```\n\nNote that the `lookingAt` method only checks the start of the string. It does not search the entire string for a match\n\n### Splitting Strings\n\nYou can split a string based on a regex pattern using the `split()` function\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('/').split('abcde') // ['abcde']\nRE2JS.compile('/').split('a/b/cc//d/e//') // ['a', 'b', 'cc', '', 'd', 'e']\nRE2JS.compile(':').split(':a::b') // ['', 'a', '', 'b']\n```\n\nThe `split()` function also supports a limit parameter\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('/').split('a/b/cc//d/e//', 3) // ['a', 'b', 'cc//d/e//']\nRE2JS.compile('/').split('a/b/cc//d/e//', 4) // ['a', 'b', 'cc', '/d/e//']\nRE2JS.compile('/').split('a/b/cc//d/e//', 9) // ['a', 'b', 'cc', '', 'd', 'e', '', '']\nRE2JS.compile(':').split('boo:and:foo', 2) // ['boo', 'and:foo']\nRE2JS.compile(':').split('boo:and:foo', 5) // ['boo', 'and', 'foo']\n```\n\n### Working with Groups\n\nRE2JS supports capturing groups in regex patterns\n\n#### Group Count\n\nYou can get the count of groups in a pattern using the `groupCount()` function\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('(.*)ab(.*)a').groupCount() // 2\nRE2JS.compile('(.*)((a)b)(.*)a').groupCount() // 4\nRE2JS.compile('(.*)(\\\\(a\\\\)b)(.*)a').groupCount() // 3\n```\n\n#### Named Groups\n\nYou can access the named groups in a pattern using the `namedGroups()` function\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('(?P\u003cfoo\u003e\\\\d{2})').namedGroups() // { foo: 1 }\nRE2JS.compile('(?\u003cbar\u003e\\\\d{2})').namedGroups() // { bar: 1 }\nRE2JS.compile('\\\\d{2}').namedGroups() // {}\nRE2JS.compile('(?P\u003cfoo\u003e.*)(?P\u003cbar\u003e.*)').namedGroups() // { foo: 1, bar: 2 }\n```\n\n#### Group Content\n\nThe `group()` method retrieves the content matched by a specific capturing group\n\n```js\nimport { RE2JS } from 're2js'\n\nconst p = RE2JS.compile('(a)(b(c)?)d?(e)')\nconst matchString = p.matcher('xabdez')\nif (matchString.find()) {\n  matchString.group(0) // 'abde'\n  matchString.group(1) // 'a'\n  matchString.group(2) // 'b'\n  matchString.group(3) // null\n  matchString.group(4) // 'e'\n}\n```\n\n#### Named Group Content\n\nThe `group()` method retrieves the content matched by a specific name of capturing group\n\n```js\nimport { RE2JS } from 're2js'\n\n// example with `(?P\u003cname\u003eexpr)`\nconst p = RE2JS.compile(\n  '(?P\u003cbaz\u003ef(?P\u003cfoo\u003eb*a(?P\u003canother\u003er+)){0,10})(?P\u003cbag\u003ebag)?(?P\u003cnomatch\u003ezzz)?'\n)\nconst matchString = p.matcher('fbbarrrrrbag')\nif (matchString.matches()) {\n  matchString.group('baz') // 'fbbarrrrr'\n  matchString.group('foo') // 'bbarrrrr'\n  matchString.group('another') // 'rrrrr'\n  matchString.group('bag') // 'bag'\n  matchString.group('nomatch') // null\n}\n\n// example with `(?\u003cname\u003eexpr)`\nconst m = RE2JS.compile(\n  '(?\u003cbaz\u003ef(?\u003cfoo\u003eb*a))'\n)\nconst mString = m.matcher('fbba')\nif (mString.matches()) {\n  mString.group('baz') // 'fbba'\n  mString.group('foo') // 'bba'\n}\n```\n\n### Replacing Matches\n\nRE2JS allows you to replace all occurrences or the first occurrence of a pattern match in a string with a specific replacement string\n\n#### Replacing All Occurrences\n\nThe `replaceAll()` method replaces all occurrences of a pattern match in a string with the given replacement\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('Frog')\n  .matcher(\"What the Frog's Eye Tells the Frog's Brain\")\n  .replaceAll('Lizard') // \"What the Lizard's Eye Tells the Lizard's Brain\"\nRE2JS.compile('(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)')\n  .matcher('abcdefghijklmnopqrstuvwxyz123')\n  .replaceAll('$10$20') // 'jb0wo0123'\n```\n\nNote that the replacement string can include references to capturing groups from the pattern\n\nParameters:\n- `replacement (String)`: The string that replaces the substrings found. Capture groups and special characters in the replacement string have special behavior. For example:\n  - `$\u0026` refers to the entire matched substring\n  - `$1, $2, ...` refer to the corresponding capture groups in the pattern\n  - `$$` inserts a literal `$`\n  - `$\u003cname\u003e` can be used to reference named capture groups\n  - on invalid group - ignore it\n- `javaMode (Boolean)`: If set to `true`, the replacement follows Java's rules for replacement. Defaults to `false`. If `javaMode = true`, changed rules for capture groups and special characters:\n  - `$0` refers to the entire matched substring\n  - `$1, $2, ...` refer to the corresponding capture groups in the pattern\n  - `\\$` inserts a literal `$`\n  - `${name}` can be used to reference named capture groups\n  - on invalid group - throw exception\n\nExamples:\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('(\\\\w+) (\\\\w+)')\n  .matcher('Hello World')\n  .replaceAll('$0 - $0') // 'Hello World - Hello World'\nRE2JS.compile('(\\\\w+) (\\\\w+)')\n  .matcher('Hello World')\n  .replaceAll('$\u0026 - $\u0026', true) // 'Hello World - Hello World'\n```\n\n#### Replacing the First Occurrence\n\nThe `replaceFirst()` method replaces the first occurrence of a pattern match in a string with the given replacement\n\n```js\nimport { RE2JS } from 're2js'\n\nRE2JS.compile('Frog')\n  .matcher(\"What the Frog's Eye Tells the Frog's Brain\")\n  .replaceFirst('Lizard') // \"What the Lizard's Eye Tells the Frog's Brain\"\nRE2JS.compile('(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)')\n  .matcher('abcdefghijklmnopqrstuvwxyz123')\n  .replaceFirst('$10$20') // 'jb0nopqrstuvwxyz123'\n```\n\nFunction support second argument `javaMode`, which work in the same way, as for `replaceAll` function\n\n### Safe Replacements\n\nWhen using untrusted user input as a replacement string, you must escape special characters so they aren't accidentally evaluated as capture groups (e.g., `$1`).\n\nUse the static method `quoteReplacement(string, javaMode)` to safely escape these characters. **Note:** You must pass the same `javaMode` boolean to `quoteReplacement` that you plan to use in `replaceAll()` / `replaceFirst()`, because the two modes use different escaping logic\n\n```js\nimport { RE2JS } from 're2js'\n\nconst text = 'The cost is 100 bucks.'\nconst regex = RE2JS.compile('100 bucks')\nconst unsafeUserInput = '$500'\n\n// Safe (Default Mode)\nconst safeDefault = RE2JS.quoteReplacement(unsafeUserInput) // \"\\$500\"\nregex.matcher(text).replaceAll(safeDefault) // \"The cost is $500.\"\n\n// Safe (Java Mode)\nconst safeJava = RE2JS.quoteReplacement(unsafeUserInput, true) // \"$$500\"\nregex.matcher(text).replaceAll(safeJava, true) // \"The cost is $500.\"\n```\n\n### Escaping Special Characters\n\nThe `quote()` method returns a literal pattern string for the specified string. This can be useful if you want to search for a literal string pattern that may contain special characters\n\n```js\nimport { RE2JS } from 're2js'\n\nconst regexp = RE2JS.quote('ab+c') // 'ab\\\\+c'\n\nRE2JS.matches(regexp, 'ab+c') // true\nRE2JS.matches(regexp, 'abc') // false\n```\n\n### Program size\n\nThe program size represents a very approximate measure of a regexp's \"cost\". Larger numbers are more expensive than smaller numbers\n\n```js\nimport { RE2JS } from 're2js'\n\nconsole.log(RE2JS.compile('^').programSize()); // Outputs: 3\nconsole.log(RE2JS.compile('a+b').programSize()); // Outputs: 5\nconsole.log(RE2JS.compile('(a+b?)').programSize()); // Outputs: 8\n```\n\n### Translating Regular Expressions\n\nThe `translateRegExp()` method preprocesses a given regular expression string to ensure compatibility with RE2JS.\nIt applies necessary transformations, such as escaping special characters, adjusting Unicode sequences, and converting named capture groups\n\n```js\nimport { RE2JS } from 're2js'\n\nconst regexp = RE2JS.translateRegExp('(?\u003cword\u003e\\\\w+)') // '(?P\u003cword\u003e\\\\w+)'\n\nRE2JS.matches(regexp, 'hello') // true\nRE2JS.matches(regexp, '123') // true\n\nconst unicodeRegexp = RE2JS.translateRegExp('\\\\u{1F600}') // '\\\\x{1F600}'\n\nRE2JS.matches(unicodeRegexp, '😀') // true\nRE2JS.matches(unicodeRegexp, '😃') // false\n```\n\n## Performance\n\nThe RE2JS engine runs more slowly compared to native RegExp objects. This reduced speed is also noticeable when comparing RE2JS to the original RE2 engine. The C++ implementation of the RE2 engine includes both NFA (Nondeterministic Finite Automaton) and DFA (Deterministic Finite Automaton) engines, as well as a variety of optimizations. Russ Cox ported a simplified version of the NFA engine to Go. Later, Alan Donovan ported the NFA-based Go implementation to Java. I then ported the NFA-based Java implementation (plus Golang stuff, which are not present in Java implementation, like checks for regular expression complexity) to a pure JS version. This is another reason why the pure JS version will perform more slowly compared to the original RE2 engine.\n\nShould you require high performance on the server side when using RE2, it would be beneficial to consider the following packages for JS:\n\n - [Node-RE2](https://github.com/uhop/node-re2/): A powerful RE2 package for Node.js\n - [RE2-WASM](https://github.com/google/re2-wasm/): This package is a WASM wrapper for RE2. Please note, as of now, it does not work in browsers\n\n### RE2JS vs JavaScript's native RegExp\n\nThese examples illustrate the performance comparison between the RE2JS library and JavaScript's native RegExp for both a simple case and a ReDoS (Regular Expression Denial of Service) scenario\n\n```js\nconst regex = 'a+'\nconst string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'\n\nRE2JS.compile(regex).matcher(string).find() // avg: 5.657783601 ms\nnew RegExp(regex).test(string) // avg: 1.504824999 ms\n```\n\nThe result shows that the RE2JS library took around **5.66 ms** on average to find a match, while the native RegExp took around **1.50 ms**. This indicates that, in this case, RegExp performed faster than RE2JS\n\n```js\nconst regex = '([a-z]+)+$'\nconst string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'\n\nRE2JS.compile(regex).matcher(string).find() // avg: 3.6155000030994415 ms\nnew RegExp(regex).test(string) // avg: 103768.25712499022 ms\n```\n\nIn the second example, a ReDoS scenario is depicted. The regular expression `([a-z]+)+$` is a potentially problematic one, as it has a nested quantifier. Nested quantifiers can cause catastrophic backtracking, which results in high processing time, leading to a potential Denial of Service (DoS) attack if a malicious user inputs a carefully crafted string.\n\nThe string is the same as in the first example, which does not pose a problem for either RE2JS or RegExp under normal circumstances. However, when dealing with the nested quantifier, RE2JS took around **3.62 ms** to find a match, while RegExp took significantly longer, around **103768.26 ms (~103 seconds)**. This demonstrates that RE2JS is much more efficient in handling potentially harmful regular expressions, thus preventing ReDoS attacks.\n\nIn conclusion, while JavaScript's native RegExp might be faster for simple regular expressions, RE2JS offers significant performance advantages when dealing with complex or potentially dangerous regular expressions. RE2JS provides protection against excessive backtracking that could lead to performance issues or ReDoS attacks.\n\n## Rationale for RE2 JavaScript port\n\nThere are several reasons that underscore the importance of having an RE2 vanilla JavaScript (JS) port.\n\nFirstly, it enables RE2 JS validation on the client side within the browser. This is vital as it allows the implementation and execution of regular expression operations directly in the browser, enhancing performance by reducing the necessity of server-side computations and back-and-forth communication.\n\nSecondly, it provides a platform for simple RE2 parsing, specifically for the extraction of regex groups. This feature is particularly useful when dealing with complex regular expressions, as it allows for the breakdown of regex patterns into manageable and identifiable segments or 'groups'.\n\nThese factors combined make the RE2 vanilla JS port a valuable tool for developers needing to work with complex regular expressions within a browser environment.\n\n## Development\n\nSome files like `CharGroup.js` and `UnicodeTables.js` is generated and should be edited in generator files\n\n```bash\n./tools/scripts/make_perl_groups.pl \u003e src/CharGroup.js\nyarn node ./tools/scripts/genUnicodeTable.js \u003e src/UnicodeTables.js\n```\n\nTo run `make_perl_groups.pl` you need to have install perl (version inside `.tool-versions`)\n\n[Playground website](https://re2js.leopard.in.ua/) maintained in `www` branch\n","funding_links":["https://www.buymeacoffee.com/leopard"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fle0pard%2Fre2js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fle0pard%2Fre2js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fle0pard%2Fre2js/lists"}