A fluent, composable API for building regular expressions
Project description
regex-recipes
A fluent, composable API for building regular expressions in Python. Say goodbye to cryptic regex strings and hello to readable, maintainable pattern building.
Overview
regex-recipes provides a Pythonic, object-oriented approach to constructing regular expressions. Instead of writing complex regex strings, you can use an intuitive builder API that makes your patterns clear and self-documenting.
from regex_recipes import Regex, Str, Digit, WordChar, Range
# Build an email pattern with readable, composable components
email = Regex(
WordChar().one_or_more(), # username
Str("@"),
WordChar().one_or_more(), # domain
Str("."),
Range("a", "z").one_or_more() # TLD
).ignore_case()
# Use it like a standard regex
email.match("user@example.com") # ✓ Matches
Features
- Fluent API: Chain methods for readable pattern construction
- Composable Components: Combine primitives into complex patterns
- Type-Safe: Full type hints for IDE support and runtime checking
- Intuitive Syntax: Use
+for concatenation,|for alternation - Operator Overloading: Natural Python expressions for regex composition
- Pattern Reusability: Build components once, use them anywhere
- No Dependencies: Pure Python implementation
- Comprehensive Coverage: Support for character classes, quantifiers, anchors, groups, and lookarounds
Installation
Install from PyPI:
pip install regex-recipes
Or install with development dependencies:
pip install regex-recipes[dev]
Quick Start
Basic Literals
from regex_recipes import Regex, Str
pattern = Regex(Str("hello"))
pattern.match("hello") # Match object
pattern.match("goodbye") # None
Concatenation
from regex_recipes import Regex, Str, Digit, WordChar
# Using direct composition
pattern = Regex(Str("User"), Digit().one_or_more())
# Equivalent to: r"User\d+"
# Or use the + operator
pattern = Str("hello") + Str(" ") + WordChar().one_or_more()
# Equivalent to: r"hello \w+"
Alternation
from regex_recipes import Str
# Using the | operator
pattern = Str("cat") | Str("dog") | Str("bird")
# Equivalent to: r"(?:cat|dog|bird)"
Core Components
Character Classes
from regex_recipes import (
Digit, # \d
WordChar, # \w (letters, digits, underscore)
Whitespace, # \s
AllChars, # .
CharSet, # [abc]
Range, # [a-z]
)
# Single digit
pattern = Digit()
# Any word character
pattern = WordChar()
# Custom character set
pattern = CharSet("aeiou") # Vowels
# Character range
pattern = Range("a", "z") # Lowercase letters
pattern = Range("A", "Z") # Uppercase letters
pattern = Range("0", "9") # Digits (same as Digit())
Quantifiers
from regex_recipes import Digit
digit = Digit()
# Exactly one (default)
digit.repeat(1)
# Zero or more: *
digit.zero_or_more()
# One or more: +
digit.one_or_more()
# Optional (zero or one): ?
digit.optional()
# Exact count: {n}
digit.repeat(3) # \d{3}
# Range: {n,m}
digit.repeat(2, 5) # \d{2,5}
# At least n: {n,}
digit.repeat(3, None) # \d{3,}
Groups & Captures
from regex_recipes import Group, NonCapturingGroup, NamedGroup, Digit
# Capturing group
group = Group(Digit().repeat(3))
# Equivalent to: (\d{3})
# Non-capturing group
group = NonCapturingGroup(Digit().repeat(3))
# Equivalent to: (?:\d{3})
# Named capturing group
group = NamedGroup("areacode", Digit().repeat(3))
# Equivalent to: (?P<areacode>\d{3})
Anchors
from regex_recipes import StartOfLine, EndOfLine, WordBoundary, Str
# Start of line: ^
pattern = StartOfLine() + Str("hello")
# End of line: $
pattern = Str("world") + EndOfLine()
# Word boundary: \b
pattern = WordBoundary() + Str("word") + WordBoundary()
Lookarounds
from regex_recipes import Lookahead, NegativeLookahead, Lookbehind, NegativeLookbehind
# Positive lookahead: (?=...)
pattern = Lookahead(Str("success"))
# Negative lookahead: (?!...)
pattern = NegativeLookahead(Str("failure"))
# Positive lookbehind: (?<=...)
pattern = Lookbehind(Str("after"))
# Negative lookbehind: (?<!...)
pattern = NegativeLookbehind(Str("before"))
Regex API
The Regex class wraps your components and provides standard regex methods:
from regex_recipes import Regex, Digit
pattern = Regex(Digit().repeat(3), "-", Digit().repeat(4))
# Match from the beginning
pattern.match("123-4567")
# Search anywhere in the string
pattern.search("Call me at 123-4567 today")
# Match the entire string
pattern.fullmatch("123-4567")
# Find all matches
pattern.findall("123-4567 and 987-6543")
# Replace matches
pattern.sub("XXX-XXXX", "Call 123-4567 now")
# Get the compiled pattern string
pattern.pattern # r"\d{3}-\d{4}"
# Flags
pattern.ignore_case()
pattern.multiline()
pattern.dotall()
Real-World Examples
Email Validation
from regex_recipes import Regex, WordChar, Str, Range
email = Regex(
WordChar().one_or_more(), # Local part
Str("@"),
WordChar().one_or_more(), # Domain
Str("."),
Range("a", "z").one_or_more() # TLD
).ignore_case()
assert email.match("user@example.com")
Phone Number Formatting
from regex_recipes import Regex, Digit, Str, Group, NamedGroup
phone = Regex(
Str("("),
NamedGroup("area", Digit().repeat(3)),
Str(")"),
NamedGroup("exchange", Digit().repeat(3)),
Str("-"),
NamedGroup("line", Digit().repeat(4))
)
assert phone.fullmatch("(555)123-4567")
URL Pattern
from regex_recipes import Regex, Str, Range, WordChar, AllChars
url = Regex(
Str("http") + (Str("s")).optional(), # https or http
Str("://"),
WordChar().one_or_more(), # Domain
Str("."),
Range("a", "z").one_or_more(), # TLD
(Str("/") + AllChars().zero_or_more()).optional() # Optional path
).ignore_case()
assert url.match("https://example.com/path")
Hex Color Code
from regex_recipes import Regex, Str, Range, CharSet
hex_color = Regex(
Str("#"),
CharSet("0123456789ABCDEFabcdef").repeat(6)
)
assert hex_color.fullmatch("#FF5733")
Builder API
For more complex patterns, use the fluent Builder class:
from regex_recipes import Builder
password = (Builder()
.digit().one_or_more() # At least one digit
.raw(r"[A-Z]").one_or_more() # At least one uppercase
.raw(r"[a-z]").one_or_more() # At least one lowercase
.raw(r"[!@#$%^&*]").one_or_more() # At least one special char
.build())
API Reference
Component Base Methods
All components inherit from Component and support:
build()→str: Generate the regex pattern string__str__()→str: Same asbuild()__add__(other)→Sequence: Concatenate components__or__(other)→Either: Create alternationzero_or_more()→ZeroOrMore: Match 0+ times (*)one_or_more()→OneOrMore: Match 1+ times (+)optional()→Optional: Match 0-1 times (?)repeat(n, m=None)→Repeat: Match n to m times
Regex Methods
match(string)→Match | None: Match at start of stringsearch(string)→Match | None: Search anywherefullmatch(string)→Match | None: Match entire stringfindall(string)→list[Any]: Find all matchessub(repl, string)→str: Replace all matchessplit(string)→list[str]: Split by patternignore_case()→Regex: Case-insensitive flagmultiline()→Regex: Multiline modedotall()→Regex: Dot matches newlinespattern→str: Get the regex pattern string
Testing
Run the test suite:
pytest tests/
With coverage:
pytest --cov=regex_recipes tests/
Development
Setup
git clone https://github.com/adityavkulkarni/regex-recipes.git
cd regex-recipes
pip install -e ".[dev]"
Code Quality
# Format code
black .
# Lint
ruff check .
# Type checking
mypy regex_recipes/
Contributing
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
v0.1.0 (Initial Release)
- Initial release with core components
- Fluent builder API
- Support for character classes, quantifiers, groups, and lookarounds
- Type hints and comprehensive documentation
Inspiration
This library is inspired by similar fluent regex builders in other languages:
- JavaScript: XRegExp
- Java: RegexBuilder
- Rust: regex
Support
For questions, issues, or suggestions, please visit the GitHub Issues page.
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 regex_recipes-0.1.0.tar.gz.
File metadata
- Download URL: regex_recipes-0.1.0.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bee37336160743a1ab62adff64ad42711635e6cc510a1811ae628583554cacb9
|
|
| MD5 |
9a22a36f22bdd23f24dd42cfd18b2b43
|
|
| BLAKE2b-256 |
4262bdea63bf80f16cf9cc2f416d5d92768383f67a1f159ad975082e79d9015f
|
File details
Details for the file regex_recipes-0.1.0-py3-none-any.whl.
File metadata
- Download URL: regex_recipes-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80001d2193da61d733f12ba9ace32b5f00742e5beccfb4d7c849a76e7e58e44c
|
|
| MD5 |
8eb9a674d8dde310e8d284020153e4d7
|
|
| BLAKE2b-256 |
98754268b59402b6aff94004dd7074abf74390ea33afec8fda325ad1ea48fc36
|