Template-based regular expression management, powered by the regex library
Project description
Replus
Template-based regular expression management, powered by the regex library.
Define regex fragments as named template keys, compose them with {{placeholders}},
and query matches through nested, named Match/Group objects — instead of
maintaining one unreadable 400-character pattern.
- Full documentation
- Fully typed, zero-magic, 100% test coverage; the only runtime dependency is
regex.
Installation
uv add replus
# or
pip install replus
Requires Python 3.11+.
Quickstart
The engine loads pattern templates from *.json files in a directory (or a plain
dict). Every key defines a reusable fragment; only the patterns under $PATTERNS
are matched at runtime.
patterns/date.json:
{
"day": ["3[01]", "[12][0-9]", "0?[1-9]"],
"month": ["0?[1-9]", "1[012]"],
"year": ["\\d{4}"],
"date": ["{{day}}/{{month}}/{{year}}", "{{year}}-{{month}}-{{day}}"],
"$PATTERNS": ["{{date}}"]
}
builds and compiles to:
(?P<date_0>(?P<day_0>3[01]|[12][0-9]|0?[1-9])/(?P<month_0>0?[1-9]|1[012])/(?P<year_0>\d{4})|(?P<year_1>\d{4})-(?P<month_1>0?[1-9]|1[012])-(?P<day_1>3[01]|[12][0-9]|0?[1-9]))
Match and query by template key — the engine resolves which numbered alternative actually matched:
from replus import Replus
engine = Replus("patterns")
for match in engine.parse("Look at this date: 1970-12-25"):
print(repr(match))
# <[Match date] span(19, 29): 1970-12-25>
date = match.group("date")
print(repr(date.group("day"))) # <Group day_1 span(27, 29) @0: '25'>
print(repr(date.group("month"))) # <Group month_1 span(24, 26) @0: '12'>
print(repr(date.group("year"))) # <Group year_1 span(19, 23) @0: '1970'>
print(match.json(indent=2)) # full nested serialization
Filter by pattern type (the template's file stem), or take the raw lazy stream:
engine.parse(text, filters=["date"]) # only date patterns
engine.parse(text, exclude=["cities"]) # everything but cities
engine.search(text) # first match or None
engine.finditer(text) # lazy, unpurged iterator
Rewrite captured groups in place — e.g. to fix OCR errors only inside matches,
with a literal string or a callable receiving the Group:
engine.sub("ID 1809900 and 1809900", {"prefix": "l"})
# 'ID l809900 and l809900'
engine.sub(text, {"prefix": lambda g: g.value.replace("1", "l")})
There's more: backreferences ({{#key}}, {{#key@2}}), unnamed/atomic groups and
lookarounds ({{?:key}}, {{?>key}}, {{?=key}}, …), repeated captures
(group.reps()), whitespace-noise injection, and overlap purging. See the
template syntax reference.
Development
git clone https://github.com/biagiodistefano/replus.git
cd replus
uv sync --all-groups
uv run pytest --cov=replus # tests (coverage gate: 100%)
uv run ruff check . # lint
uv run ruff format . # format
uv run ty check # type check
uv run sphinx-build -b html docs docs/_build # docs
License
MIT © Biagio Distefano
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file replus-1.0.0.tar.gz.
File metadata
- Download URL: replus-1.0.0.tar.gz
- Upload date:
- Size: 12.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1986c0825f97beffc3eed80b5061cb38da8889a3b420004770eb4a8db505e1dc
|
|
| MD5 |
a1337ae8a004302e0188bd58afeba2e5
|
|
| BLAKE2b-256 |
1ea29effa892e9cbfcd6a6c60b9ccb1b96872eda82b223d75e28fc4eaf74c084
|
Provenance
The following attestation bundles were made for replus-1.0.0.tar.gz:
Publisher:
release.yml on biagiodistefano/replus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
replus-1.0.0.tar.gz -
Subject digest:
1986c0825f97beffc3eed80b5061cb38da8889a3b420004770eb4a8db505e1dc - Sigstore transparency entry: 2167742777
- Sigstore integration time:
-
Permalink:
biagiodistefano/replus@c0208568f8920602465e10b2ab6c5647f50858ee -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/biagiodistefano
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c0208568f8920602465e10b2ab6c5647f50858ee -
Trigger Event:
release
-
Statement type:
File details
Details for the file replus-1.0.0-py3-none-any.whl.
File metadata
- Download URL: replus-1.0.0-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bd6e9d94b9bf7e73cf98a1fe0361c940c951925e4d1f171c6da3cd09183040e
|
|
| MD5 |
fccfc1a7c0b23595dc0d0810cb3913d1
|
|
| BLAKE2b-256 |
b1a8221f7f697f4c180b806b5e66c61d7afb4a7903b6f122237335dba932c69c
|
Provenance
The following attestation bundles were made for replus-1.0.0-py3-none-any.whl:
Publisher:
release.yml on biagiodistefano/replus
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
replus-1.0.0-py3-none-any.whl -
Subject digest:
1bd6e9d94b9bf7e73cf98a1fe0361c940c951925e4d1f171c6da3cd09183040e - Sigstore transparency entry: 2167742783
- Sigstore integration time:
-
Permalink:
biagiodistefano/replus@c0208568f8920602465e10b2ab6c5647f50858ee -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/biagiodistefano
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c0208568f8920602465e10b2ab6c5647f50858ee -
Trigger Event:
release
-
Statement type: