Skip to main content

qre - like re, but cuter

PyPI - Version License: MIT tests

Samples
Pattern "* pattern"
Input "First pattern"
Result 👍🏼
Pattern "World's [] pattern"
Input "World's coolest pattern"
Result ["coolest"]
Pattern "product id: [product_id], units: [units: int], price: [unit_price: decimal]"
Input "Product ID: A123, Units: 3, Price: 1.23" (case-insensitive)
Result {"product_id": "A123", "units": 3, "unit_price": Decimal("1.23")}

This package owes everything, including most of the codebase, to Thomas Feldtmann's simplematch. All poor design decisions are mine. See this collection for other alternatives.

Status: Comprehensively tested but never used for anything real. All evolution is expected to be incremental.

Quick start

pip install qre

My first little match:

import qre

assert qre.search("in [place]", "Match made in heaven") == {"place": "heaven"}

qre is mostly focused on collecting named groups from the input strings, so the return value is an easy-to-access dict. Groups are denoted with brackets, which means that patterns are friendly with f-strings.

For unnamed groups the returned object has been tweaked a little bit - they can be found as a list in the unnamed attribute:

assert qre.match("[] [:int]", "Lesson 1").unnamed == ["Lesson", 1]

Type specifiers can be used with both named and unnamed groups. They act both as specs for the pattern to find and, when applicable, as converters to the right type.

Currently available types are:

  • int
  • float
  • decimal
  • date (ISO)
  • datetime (ISO)
  • uuid
  • letters
  • identifier (letters plus numbers and underscore)
  • email
  • url
  • ipv4
  • ipv6
  • creditcard
  • open (any one of (, [, {)
  • close (), ], or })

You can register your own types and conversions with register_type(name, regex, converter=str). As qre's goal is not to replicate the functionality of re, this can also act as the "escape hatch" when you need just a little bit more than what qre offers.

Here's how to use register_type to turn an emoji into a textual description:

qre.register_type("mood", r"[😀😞]", lambda emoji: {"😀": "good", "😞": "bad"}.get(emoji, "unknown"))

assert qre.search("[mood:mood]", "I'm feeling 😀 today!") == {"mood": "good" }

Note that register_type manipulates a global object, so you only need to register custom types once, probably somewhere towards the start of your program.

PRs for generally useful types are highly welcome.

Matching functions

Matching functions expect a pattern and a string to match against. The optional case_sensitive argument is true by default.

  • match - Match pattern against the whole of the string
  • match_start - Match pattern against the beginning of the string
  • match_end - Match pattern against the end of the string
  • search - Return the first match of the pattern in the string
  • search_all - Return all matches of the pattern in the string as a list

All of the functions always return an object that is either truthy or falsy depending on whether there was a match or not. They never return None, and the unnamed attribute contains at least an empty list, so the returned object is always safe to iterate.

Alternatively, you can use the Matcher object. It has the following useful attributes:

  • regex for debugging the generated regex, or for copying it for use with plain re
  • converters for debugging the converters in use
matcher = qre.Matcher("value: [quantitative:float]|[qualitative]", case_sensitive=False)
assert matcher.match("Value: 1.0") == {"quantitative": 1.0}  # Or any of the other functions above
assert matcher.regex == "value:\\ (?P<quantitative>[+-]?(?:[0-9]*[.])?[0-9]+)|(?P<qualitative>.*)"
assert matcher.converters == {'quantitative': float}

As a final usage scenario, you can call qre on the command line:

$ python qre.py
usage: qre.py [-h] [--regex] pattern string

Pattern syntax summary

  • Wildcards:
    • * - any character 0+ times
    • + - any 1 character
    • ? - any 1 character, maybe
  • Operators:
    • | - either of two characters or groups
  • Groups:
    • [name] - named group called "name", returned in the main dict.
    • [] - unnamed group, returned in the unnamed list
    • [name:4], [:4] - group that is 4 characters wide
    • [name:int], [:int] - group that matches the type and is converted to that Python type
  • Escaping:
    • [*], [+], [?], [|] - literal symbol, not wildcard
    • [[, ]] - literal brackets, not groups

Metadata

Release files for qre 22.10.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qre 22.10.2
File Size Uploaded Provenance Actions
qre-22.10.2.tar.gz 8.5 kB Without provenance Details for qre-22.10.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for qre 22.10.2
File Interpreter ABI Platform Actions
qre-22.10.2-py3-none-any.whl Python 3 none any Details for qre-22.10.2-py3-none-any.whl

Total release size: 16.4 kB

Release files / qre-22.10.2.tar.gz

Download URL qre-22.10.2.tar.gz
Size 8.5 kB
Tags Source
SHA-256 checksum
How to use checksums
607acb84e9f2611d2c4b3fb10cc476e113a2f9eac2e9e040ecffa17691dde5cb
BLAKE2b-256 checksum
How to use checksums
8bc90d79c6176ddb0cc9fda59800d6e744a9564204ecff6735721e6c8a6a0efe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.14 CPython/3.10.6 Darwin/21.6.0

Release files / qre-22.10.2-py3-none-any.whl

Download URL qre-22.10.2-py3-none-any.whl
Size 7.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a32c1e77c83dac0bfc5c0a1c018e68fef3470db7ee27587c004bf90d46ad1ef
BLAKE2b-256 checksum
How to use checksums
d595647ce3262b191df880f0fb6ac8b79b8cb273b7b321472a1c38dadd8c6ef4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.14 CPython/3.10.6 Darwin/21.6.0

Security for qre 22.10.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page