{"id":19213619,"url":"https://github.com/0xsobky/regaxor","last_synced_at":"2025-09-07T08:36:57.421Z","repository":{"id":111912485,"uuid":"124936378","full_name":"0xSobky/Regaxor","owner":"0xSobky","description":"A regular expression fuzzer.","archived":false,"fork":false,"pushed_at":"2018-03-13T00:02:00.000Z","size":1879,"stargazers_count":43,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-12T22:18:46.199Z","etag":null,"topics":["fuzzing","regex","regexp","regular-expression","tools"],"latest_commit_sha":null,"homepage":"https://0xsobky.github.io/Regaxor/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0xSobky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-03-12T18:53:49.000Z","updated_at":"2024-11-12T04:46:50.000Z","dependencies_parsed_at":"2023-09-08T16:30:57.577Z","dependency_job_id":null,"html_url":"https://github.com/0xSobky/Regaxor","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/0xSobky/Regaxor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xSobky%2FRegaxor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xSobky%2FRegaxor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xSobky%2FRegaxor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xSobky%2FRegaxor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0xSobky","download_url":"https://codeload.github.com/0xSobky/Regaxor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xSobky%2FRegaxor/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268074770,"owners_count":24191611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["fuzzing","regex","regexp","regular-expression","tools"],"created_at":"2024-11-09T14:06:43.014Z","updated_at":"2025-07-31T17:08:02.685Z","avatar_url":"https://github.com/0xSobky.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Regaxor\n\nRegaxor (RegExp Haxxor) is a regular expression fuzzer, written in ECMAScript 6.\n\n\n## Why do we need it?\n\nWhatever you're coding, regular expressions come in handy in various situations and are often very useful but can also be very tricky to get right. Writing a regex that matches what you expect is easy; writing a regex that ___only___ matches what you expect is virtually impossible (except in trivial cases). That's where this tool comes into play—by fuzzing regular expressions, we can easily detect any issues/gotchas before learning about them the hard way.\n\n\n### Regex gotchas?!\n\nThe following are just some examples of common regex gotchas (NVM the funny titles):\n\n1. In the beginning was the Word\n```javascript\nlet badRegex = /https?:\\/\\/example\\.com\\/[\\w]*/;\nlet str = 'Word\\nhttps://example.com/';\nstr.match(badRegex);\n// Output: [\"https://example.com/\", index: 5, input: \"Word↵https://example.com/\", groups: undefined]\n\nlet goodRegex = /^https?:\\/\\/example\\.com\\/[\\w]*/;\nstr.match(goodRegex);\n// Output: null\n\n'https://example.com/'.match(goodRegex);\n// Output: [\"https://example.com/\", index: 0, input: \"https://example.com/\", groups: undefined]\n\n```\n\n2. Catch 22\n```javascript\nlet badRegex = /[123]|22/g;\nbadRegex.exec('22');\n// Output: [\"2\", index: 0, input: \"22\", groups: undefined]\n\nlet goodRegex = /22|[123]/g;\ngoodRegex.exec('22');\n// Output: [\"22\", index: 0, input: \"22\", groups: undefined]\n\n```\n\n3. One sneaky dot\n```javascript\nlet str = 'https://exampleXcom';\nlet badRegex = /^\\w+:\\/\\/example.com$/;\nbadRegex.exec(str);\n// Output: [\"https://exampleXcom\", index: 0, input: \"https://exampleXcom\", groups: undefined]\n\nlet goodRegex = /^\\w+:\\/\\/example\\.com$/;\ngoodRegex.exec(str);\n// Output: null\n\ngoodRegex.exec('https://example.com');\n// Output: [\"https://example.com\", index: 0, input: \"https://example.com\", groups: undefined]\n\n```\n\n4. All or nothing\n```javascript\nlet badRegex = /^\\.*|\\d+$/g;\n'abc'.match(badRegex);\n// Output: [\"\"]\n\nlet goodRegex = /^[\\d.]+$/g;\n'abc'.match(goodRegex);\n// Output: null\n\n'12.3'.match(goodRegex);\n// Output: [\"12.3\"]\n\n```\n\n5. The word boundary trap\n```javascript\nlet badRegex = /word/;\nbadRegex.exec('aworda');\n// Output: [\"word\", index: 1, input: \"aworda\", groups: undefined]\n\nlet goodRegex = /\\bword\\b/;\ngoodRegex.exec('aworda');\n// Output: null\n\ngoodRegex.exec('a word');\n// Output: [\"word\", index: 2, input: \"a word\", groups: undefined]\n\n```\n\n6. Multiline confusion\n```javascript\nlet badRegex = /a.*b/;\nbadRegex.exec('a\\nb');\n// Output: null\n\nlet alsoBadRegex = /a.*b/m;\nalsoBadRegex.exec('a\\nb');\n// Output: null\n\nlet goodRegex = /a[^]*b/;\ngoodRegex.exec('a\\nb');\n// Output: [\"a↵b\", index: 0, input: \"a↵b\", groups: undefined]\n\n```\n\n7. One escape is not enough\n```javascript\nlet badRegex = 'x\\.com';\nnew RegExp(badRegex).exec('xycom');\n// Output: [\"xycom\", index: 0, input: \"xycom\", groups: undefined]\n\nlet goodRegex = 'x\\\\.com';\nnew RegExp(goodRegex).exec('xycom');\n// Output: null\n\nnew RegExp(goodRegex).exec('x.com');\n// Output: [\"x.com\", index: 0, input: \"x.com\", groups: undefined]\n\n```\n\n8. Escaping the escaping\n```javascript\nlet str = 'double\\\\\"quotes\"';\n\n// Bad.\nstr.replace(/\"/g, '\\\\\"');\n// Output: \"double\\\\\"quotes\\\"\"\n\n// Not bad but not recommended.\nstr.replace(/(\\\\|\")/g, '\\\\$1');\n// Output: \"double\\\\\\\"quotes\\\"\"\n\n// Better.\nstr.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n// Output: \"double\\\\\\\"quotes\\\"\"\n\n```\n\n9. Too greedy\n```javascript\nlet badRegex = /\u003c.+\u003e\u003c\\/.+\u003e/g;\nlet tags = '\u003ctag attribute=\"foo\"\u003e\u003c/tag\u003e\u003ctag id=\"foo\"\u003e\u003c/tag\u003e';\nbadRegex.exec(tags);\n// Output: [\"\u003ctag attribute=\"foo\"\u003e\u003c/tag\u003e\u003ctag id=\"foo\"\u003e\u003c/tag\u003e\", index: 0, input: \"\u003ctag attribute=\"foo\"\u003e\u003c/tag\u003e\u003ctag id=\"foo\"\u003e\u003c/tag\u003e\", groups: undefined]\n\nlet notBadRegex = /\u003c.+?\u003e\u003c\\/.+?\u003e/g;\nnotBadRegex.exec(tags);\n// Output: [\"\u003ctag attribute=\"foo\"\u003e\u003c/tag\u003e\", index: 0, input: \"\u003ctag attribute=\"foo\"\u003e\u003c/tag\u003e\u003ctag id=\"foo\"\u003e\u003c/tag\u003e\", groups: undefined]\n\nnotBadRegex.exec(tags);\n// Output: [\"\u003ctag id=\"foo\"\u003e\u003c/tag\u003e\", index: 27, input: \"\u003ctag attribute=\"foo\"\u003e\u003c/tag\u003e\u003ctag id=\"foo\"\u003e\u003c/tag\u003e\", groups: undefined]\n\n```\n\n10. The misplaced hyphen\n```javascript\nlet badRegex = /[\\w -$]+/;\n'#'.match(badRegex);\n// Output: [\"#\", index: 0, input: \"#\", groups: undefined]\n\nlet goodRegex = /[\\w $-]+/;\n'#'.match(goodRegex);\n// Output: null\n\n'$100 USD'.match(goodRegex);\n// Output: [\"$100 USD\", index: 0, input: \"$100 USD\", groups: undefined]\n\n```\n\nAt times, writing a regex can feel like walking in a minefield. At other times, regular expressions are the wrong answer—or as Jamie Zawinski puts it `Some people, when confronted with a problem, think \"I know, I'll use regular expressions.\" Now they have two problems.`. So, especially in security-sensitive contexts, you're probably better off not using regular expressions unless you really have to....\n\n\n## Screenshot(s)\n\n[![screenshot.png](https://github.com/0xSobky/Regaxor/raw/master/data/images/screenshot.png)](https://github.com/0xSobky/Regaxor/raw/master/data/images/screenshot.png)\n\n\n## Credits\n\n* [@0xSobky](https://twitter.com/0xSobky)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xsobky%2Fregaxor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0xsobky%2Fregaxor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xsobky%2Fregaxor/lists"}