{"id":16014677,"url":"https://github.com/pmonks/rencg","last_synced_at":"2025-03-18T03:30:30.483Z","repository":{"id":180554868,"uuid":"665324015","full_name":"pmonks/rencg","owner":"pmonks","description":"A micro-library for Clojure that provides first class support for named-capturing groups in regular expressions","archived":false,"fork":false,"pushed_at":"2024-10-27T00:21:29.000Z","size":456,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"dev","last_synced_at":"2024-10-27T01:31:09.045Z","etag":null,"topics":["clojure","regex"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pmonks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-12T00:51:13.000Z","updated_at":"2024-10-27T00:21:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"d2257aa0-7b53-4e96-ade4-106308063dfc","html_url":"https://github.com/pmonks/rencg","commit_stats":{"total_commits":53,"total_committers":1,"mean_commits":53.0,"dds":0.0,"last_synced_commit":"8dc66374f642f57f97c233bfd3cbf1b4c015894e"},"previous_names":["pmonks/rencg"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmonks%2Frencg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmonks%2Frencg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmonks%2Frencg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmonks%2Frencg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pmonks","download_url":"https://codeload.github.com/pmonks/rencg/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221704872,"owners_count":16866847,"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","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":["clojure","regex"],"created_at":"2024-10-08T15:04:45.355Z","updated_at":"2025-03-18T03:30:30.478Z","avatar_url":"https://github.com/pmonks.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"| | | |\n|---:|:---:|:---:|\n| [**release**](https://github.com/pmonks/rencg/tree/release) | [![CI](https://github.com/pmonks/rencg/actions/workflows/ci.yml/badge.svg?branch=release)](https://github.com/pmonks/rencg/actions?query=workflow%3ACI+branch%3Arelease) | [![Dependencies](https://github.com/pmonks/rencg/actions/workflows/dependencies.yml/badge.svg?branch=release)](https://github.com/pmonks/rencg/actions?query=workflow%3Adependencies+branch%3Arelease) |\n| [**dev**](https://github.com/pmonks/rencg/tree/dev)  | [![CI](https://github.com/pmonks/rencg/actions/workflows/ci.yml/badge.svg?branch=dev)](https://github.com/pmonks/rencg/actions?query=workflow%3ACI+branch%3Adev) | [![Dependencies](https://github.com/pmonks/rencg/actions/workflows/dependencies.yml/badge.svg?branch=dev)](https://github.com/pmonks/rencg/actions?query=workflow%3Adependencies+branch%3Adev) |\n\n[![Latest Version](https://img.shields.io/clojars/v/com.github.pmonks/rencg)](https://clojars.org/com.github.pmonks/rencg/) [![Open Issues](https://img.shields.io/github/issues/pmonks/rencg.svg)](https://github.com/pmonks/rencg/issues) [![License](https://img.shields.io/github/license/pmonks/rencg.svg)](https://github.com/pmonks/rencg/blob/release/LICENSE) [![Vulnerabilities](https://github.com/pmonks/rencg/actions/workflows/vulnerabilities.yml/badge.svg?branch=dev)](https://github.com/pmonks/rencg/actions?query=workflow%3Avulnerabilities+branch%3Adev)\n\n\n# rencg\n\nA micro-library for Clojure that provides first class support for accessing the values of [named-capturing groups](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html#groupname) in regular expressions. It has no dependencies, other than on Clojure and the JVM versions it supports, and is [only around 100 lines of code](https://github.com/pmonks/rencg/blob/release/src/rencg/).\n\n#### Does `rencg` work on older JVMs that don't have the [`.namedGroups()` API](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/regex/Pattern.html#namedGroups())?\n\nYes. On older (pre v20) JVMs, `rencg` [falls back on manually parsing regexes to determine the named capturing groups](https://github.com/pmonks/rencg/blob/release/src/rencg/non_native.clj).\n\n#### Why not [rufoa/named-re](https://github.com/rufoa/named-re)?\n\nBecause that library [monkey patches core Clojure](https://github.com/rufoa/named-re/blob/master/src/named_re/core.clj#L26-L32), which may break other code.\n\n## Installation\n\n`rencg` is available as a Maven artifact from [Clojars](https://clojars.org/com.github.pmonks/rencg).\n\n### Trying it Out\n\n#### Clojure CLI\n\n```shell\n$ clj -Sdeps '{:deps {com.github.pmonks/rencg {:mvn/version \"RELEASE\"}}}'\n```\n\n#### Leiningen\n\n```shell\n$ lein try com.github.pmonks/rencg\n```\n\n#### deps-try\n\n```shell\n$ deps-try com.github.pmonks/rencg\n```\n\n### Demo\n\n```clojure\n(require '[rencg.api :as rencg])\n\n\n;; re-matches-ncg - for when you want to match the entire input\n(rencg/re-matches-ncg #\"(?\u003cfoo\u003efoo)\" \"bar\")\n;=\u003e nil\n\n(rencg/re-matches-ncg #\"(?\u003cfoo\u003efoo)\" \"foo\")\n;=\u003e {:start 0, :end 3, :match \"foo\", \"foo\" \"foo\"}\n\n(rencg/re-matches-ncg #\"(?\u003cfoo\u003efoo)+\" \"foofoo\")\n;=\u003e {:start 0, :end 6, :match \"foofoo\", \"foo\" \"foo\"}\n\n; Note: Java named capturing groups only capture a single value from the input, even if the\n; group is present multiple times. Also, the start and end indexes are for the entire match,\n; not where the named capturing groups are found (obviously, since there may be many named\n; capturing groups all of which have different start and end indexes).\n\n(rencg/re-matches-ncg #\"((?\u003cfoo\u003efoo)|(?\u003cbar\u003ebar))+\" \"foobarfoobarfoobarfoobar\")\n;=\u003e {:start 0, :end 24, :match \"foobarfoobarfoobarfoobar\", \"foo\" \"foo\", \"bar\" \"bar\"}\n\n; This last example also shows the value of using named capturing groups instead of numbered\n; capturing groups (the latter being brittle, since non-named groups conflate grouping and\n; capture)\n\n\n;; re-seq-ncg - for when you want all matches of a named capturing group that exist within\n;;              the input\n(rencg/re-seq-ncg #\"((?\u003cfoo\u003efoo)|(?\u003cbar\u003ebar))\" \"foobarfoobarfoobarfoobar\")\n;=\u003e ({:start 0, :end 3, :match \"foo\", \"foo\" \"foo\"}\n;    {:start 3, :end 6, :match \"bar\", \"bar\" \"bar\"}\n;    {:start 6, :end 9, :match \"foo\", \"foo\" \"foo\"}\n;    {:start 9, :end 12, :match \"bar\", \"bar\" \"bar\"}\n;    {:start 12, :end 15, :match \"foo\", \"foo\" \"foo\"}\n;    {:start 15, :end 18, :match \"bar\", \"bar\" \"bar\"}\n;    {:start 18, :end 21, :match \"foo\", \"foo\" \"foo\"}\n;    {:start 21, :end 24, :match \"bar\", \"bar\" \"bar\"})\n\n\n;; re-find-ncg - for when you want to extract something specific from the input, using\n;;               standard Clojure map lookups\n(get (rencg/re-find-ncg #\"(?i)(?\u003cfoo\u003efoo)\" \"THIS IS SOME TEXT WITH FOO IN IT\") \"foo\")\n;=\u003e \"FOO\"\n```\n\n## Usage\n\n[API documentation is available here](https://pmonks.github.io/rencg/), or [here on cljdoc](https://cljdoc.org/d/com.github.pmonks/rencg/), and the [unit tests](https://github.com/pmonks/rencg/blob/release/test/rencg/api_test.clj) are also worth perusing to see worked examples.\n\n## Contributor Information\n\n[Contributing Guidelines](https://github.com/pmonks/rencg/blob/release/.github/CONTRIBUTING.md)\n\n[Bug Tracker](https://github.com/pmonks/rencg/issues)\n\n[Code of Conduct](https://github.com/pmonks/rencg/blob/release/.github/CODE_OF_CONDUCT.md)\n\n### Developer Workflow\n\nThis project uses the [git-flow branching strategy](https://nvie.com/posts/a-successful-git-branching-model/), and the permanent branches are called `release` and `dev`.  Any changes to the `release` branch are considered a release and auto-deployed (JARs to Clojars, API docs to GitHub Pages, etc.).\n\nFor this reason, **all development must occur either in branch `dev`, or (preferably) in temporary branches off of `dev`.**  All PRs from forked repos must also be submitted against `dev`; the `release` branch is **only** updated from `dev` via PRs created by the core development team.  All other changes submitted to `release` will be rejected.\n\n### Build Tasks\n\n`rencg` uses [`tools.build`](https://clojure.org/guides/tools_build). You can get a list of available tasks by running:\n\n```\nclojure -A:deps -T:build help/doc\n```\n\nOf particular interest are:\n\n* `clojure -T:build test` - run the unit tests\n* `clojure -T:build lint` - run the linters (clj-kondo and eastwood)\n* `clojure -T:build ci` - run the full CI suite (check for outdated dependencies, run the unit tests, run the linters)\n* `clojure -T:build install` - build the JAR and install it locally (e.g. so you can test it with downstream code)\n\nPlease note that the `release` and `deploy` tasks are restricted to the core development team (and will not function if you run them yourself).\n\n## License\n\nCopyright © 2023 Peter Monks\n\nDistributed under the [Mozilla Public License, version 2.0](https://www.mozilla.org/en-US/MPL/2.0/).\n\nSPDX-License-Identifier: [`MPL-2.0`](https://spdx.org/licenses/MPL-2.0)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmonks%2Frencg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmonks%2Frencg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmonks%2Frencg/lists"}