PyPcre 0.2.15__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pypcre-0.2.15 → pypcre-0.3.0}/PKG-INFO +77 -34
- {pypcre-0.2.15 → pypcre-0.3.0}/PyPcre.egg-info/PKG-INFO +77 -34
- {pypcre-0.2.15 → pypcre-0.3.0}/README.md +76 -33
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/pcre.py +92 -23
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/re_compat.py +19 -15
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/pcre2.c +262 -19
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/pcre2_module.h +10 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pyproject.toml +1 -1
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_clobber_thread.py +1 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/LICENSE +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/MANIFEST.in +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/PyPcre.egg-info/SOURCES.txt +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/PyPcre.egg-info/dependency_links.txt +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/PyPcre.egg-info/top_level.txt +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/__init__.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/_stdlib_re.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/cache.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/error.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/flags.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre/threads.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/atomic_compat.h +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/cache.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/error.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/flag.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/jit_support.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/memory.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/pattern_cache.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/pcre2.h +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/string_helpers.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/pcre_ext/util.c +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/setup.cfg +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/setup.py +1 -1
- {pypcre-0.2.15 → pypcre-0.3.0}/setup_utils.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_accuracy.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_api_parity.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_basic.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_bench_string.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_benchmark.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_bytes.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_cache.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_clobber.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_core.py +1 -1
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_errors.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_flags.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_jit.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_memory.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_module.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_pattern.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_setup_utils_multiarch.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_simd.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_threaded_backend.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_transformers_regex.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_utf8.py +0 -0
- {pypcre-0.2.15 → pypcre-0.3.0}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPcre
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
|
|
5
5
|
Author-email: ModelCloud <qubitium@modelcloud.ai>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -27,10 +27,14 @@ Dynamic: license-file
|
|
|
27
27
|
# SPDX-License-Identifier: Apache-2.0
|
|
28
28
|
# Contact: qubitium@modelcloud.ai, x.com/qubitium
|
|
29
29
|
-->
|
|
30
|
+
<div align=center>
|
|
31
|
+
<img width="400" height="1024" alt="image" src="https://github.com/user-attachments/assets/92964c3a-f82e-4949-bd27-278f57c62d9f" />
|
|
32
|
+
</div>
|
|
33
|
+
<h1 align="center">PyPcre (Python PCRE2 Binding) 🧬</h1>
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
<p align=center>
|
|
36
|
+
Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compatible API. ⚡
|
|
37
|
+
</p>
|
|
34
38
|
|
|
35
39
|
<p align="center">
|
|
36
40
|
<a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
|
|
@@ -42,52 +46,92 @@ Modern `nogil` Python bindings for the PCRE2 library with `stdlib.re` API compat
|
|
|
42
46
|
|
|
43
47
|
|
|
44
48
|
|
|
45
|
-
## Latest News
|
|
46
|
-
*
|
|
47
|
-
* 03/
|
|
48
|
-
* 03/
|
|
49
|
-
* 02/
|
|
50
|
-
*
|
|
51
|
-
*
|
|
49
|
+
## Latest News 🚀
|
|
50
|
+
* 04/13/2026 [0.3.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.3.0): Lower-overhead public `Match` objects, faster hot-path `match()` / `search()` / `fullmatch()` / `findall()`, and tighter free-threaded execution. ⚡
|
|
51
|
+
* 03/22/2026 [0.2.15](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.15): Python 3.15 `re` compatibility (`prefixmatch`, `NOFLAG`) ✅
|
|
52
|
+
* 03/21/2026 [0.2.14](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.14): Python 3.14 compatibility 🐍
|
|
53
|
+
* 03/02/2026 [0.2.11](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.11): Auto-detect `Visual Studio` in Windows environments during install and compile. 🪟
|
|
54
|
+
* 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow a `Visual Studio` (VS) compiler version check override via an environment variable. 🧰
|
|
55
|
+
* 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux OS compatibility when both x86_64 and i386 `pcre2` libraries are installed. 🐧
|
|
56
|
+
* 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed the dependency on a system `python3-dev` package. `Python.h` will be downloaded optimistically from python.org when needed. 📦
|
|
52
57
|
* 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance across all APIs. Expanded CI test coverage. FreeBSD, Solaris, and Windows compatibility validated.
|
|
53
58
|
* 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread-safe, with auto JIT, auto pattern caching, and optimistic linking to the system library for fast installs.
|
|
54
59
|
|
|
55
|
-
## Why PyPcre
|
|
60
|
+
## Why PyPcre ⚡
|
|
61
|
+
|
|
62
|
+
PyPcre pairs Python's familiar `re`-compatible API with the real `PCRE2` engine. You keep the ergonomics of the standard library while gaining a more capable regex engine, optional JIT, explicit threading support, and a binding designed and tested for free-threaded Python. 🧠⚡
|
|
63
|
+
|
|
64
|
+
### Big Wins 🏆
|
|
65
|
+
|
|
66
|
+
- 🧬 **Full power of PCRE2**: PyPcre uses the real `PCRE2` engine, so you get native compile options, semantics, JIT, and upstream tuning.
|
|
67
|
+
- 🔥 **More expressive regex syntax**: `PCRE2` supports constructs beyond stdlib `re`, including atomic groups `(?>...)`, possessive quantifiers `++`, branch-reset groups `(?|...)`, richer lookarounds, and backtracking control verbs like `(*SKIP)(*FAIL)`.
|
|
68
|
+
- 🧵 **Thread-safe into `nogil`**: PyPcre is built for `PYTHON_GIL=0`, with CI coverage, lock-aware caches, reusable match/JIT resources, and `parallel_map()` for multi-subject fan-out.
|
|
69
|
+
- ⚡ **Fast on real workloads**: `PCRE2` JIT plus cached compiled patterns lets PyPcre match or beat `re` and `regex` on many common scans, especially multiline searches, lookaround-heavy patterns, and free-threaded execution.
|
|
70
|
+
- 🛡️ **Safer operational story**: PyPcre prefers the system `libpcre2-8` shared library so normal OS package updates can bring security and bug-fix benefits without a bundled fork.
|
|
71
|
+
- ✅ **Validated thoroughly**: the project runs API tests, fuzz tests, memory-safety checks, local `valgrind` leak checks, and `massif` heap profiles. Recent local profiling found `0` definite leaks and `0` possible leaks in both the public API and raw binding paths.
|
|
72
|
+
|
|
73
|
+
### Quick Comparison 🥊
|
|
74
|
+
|
|
75
|
+
| Area | PyPcre | `stdlib.re` | `regex` |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| Engine | Full `PCRE2` ✅ | CPython stdlib engine | Separate engine, not `PCRE2` |
|
|
78
|
+
| `PCRE2` syntax and flags | Full access ✅ | No | No |
|
|
79
|
+
| Syntax power | Very rich ✅ | More limited | Rich, but different from `PCRE2` |
|
|
80
|
+
| JIT execution | `PCRE2` JIT ✅ | No | No |
|
|
81
|
+
| `re`-compatible API surface | Stable and familiar ✅ | Native | Similar, but not the main goal |
|
|
82
|
+
| Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit PyPcre-style layer | Not a project focus here |
|
|
83
|
+
| Built-in threaded subject fan-out | `parallel_map()` ✅ | No | No |
|
|
84
|
+
| System library updates | Uses system `libpcre2-8` by default ✅ | N/A | N/A |
|
|
85
|
+
|
|
86
|
+
### Benchmark Highlights 🏁
|
|
87
|
+
|
|
88
|
+
Measured on a `Python 3.14.3` free-threaded build on x86_64 Linux with compiled-pattern reuse. Times are best-of-5; lower is better.
|
|
89
|
+
|
|
90
|
+
| Workload | Operation | PyPcre | `re` | `regex` | PyPcre edge |
|
|
91
|
+
| --- | --- | ---: | ---: | ---: | --- |
|
|
92
|
+
| First `ERROR` line in a multiline log buffer | `search` | `3.68 ms` | `51.72 ms` | `5.67 ms` | `14.0x` vs `re`, `1.54x` vs `regex` |
|
|
93
|
+
| Extract only `WARN` / `ERROR` lines | `findall` | `6.41 ms` | `91.84 ms` | `91.14 ms` | `14.3x` vs `re`, `14.2x` vs `regex` |
|
|
94
|
+
| Per-line full-name extraction | `findall` | `22.28 ms` | `172.38 ms` | `218.29 ms` | `7.74x` vs `re`, `9.80x` vs `regex` |
|
|
95
|
+
| Lookbehind + negative-lookahead extraction | `findall` | `50.23 ms` | `53.35 ms` | `57.03 ms` | `1.06x` vs `re`, `1.14x` vs `regex` |
|
|
96
|
+
| UUID extraction | `findall` | `77.49 ms` | `83.19 ms` | `134.87 ms` | `1.07x` vs `re`, `1.74x` vs `regex` |
|
|
97
|
+
| Boundary-aware token scan | `findall` | `127.76 ms` | `128.03 ms` | `146.37 ms` | effectively tied with `re`, `1.15x` vs `regex` |
|
|
56
98
|
|
|
57
|
-
|
|
99
|
+
### Free-Threaded Benchmark Highlights 🧵
|
|
58
100
|
|
|
59
|
-
|
|
101
|
+
Measured in the same environment with `8` threads sharing one compiled pattern. Times are best-of-3; lower is better.
|
|
60
102
|
|
|
61
|
-
|
|
103
|
+
| Workload | Threads | PyPcre | `re` | `regex` | PyPcre edge |
|
|
104
|
+
| --- | ---: | ---: | ---: | ---: | --- |
|
|
105
|
+
| First `ERROR` line in a multiline log buffer | `8` | `25.34 ms` | `38.83 ms` | `40.34 ms` | `1.53x` vs `re`, `1.59x` vs `regex` |
|
|
106
|
+
| Extract only `WARN` / `ERROR` lines | `8` | `28.58 ms` | `65.54 ms` | `73.55 ms` | `2.29x` vs `re`, `2.57x` vs `regex` |
|
|
107
|
+
| Per-line full-name extraction | `8` | `31.68 ms` | `123.44 ms` | `164.80 ms` | `3.90x` vs `re`, `5.20x` vs `regex` |
|
|
62
108
|
|
|
63
|
-
|
|
109
|
+
PyPcre is the stronger all-around choice when you want more than the baseline: full `PCRE2` features, more expressive syntax, JIT, explicit free-threaded support, and a stable `re`-compatible API surface. It keeps Python ergonomics while giving you a substantially more capable engine. 🚀
|
|
64
110
|
|
|
65
|
-
## Installation
|
|
111
|
+
## Installation 📦
|
|
66
112
|
|
|
67
113
|
```bash
|
|
68
114
|
pip install PyPcre
|
|
69
115
|
```
|
|
70
116
|
|
|
71
|
-
|
|
117
|
+
By default, the package links against the system `libpcre2-8` shared library for fast installs and to inherit OS security updates. See [Building](#building) for manual build details.
|
|
72
118
|
|
|
73
|
-
## Platform Support (Validated)
|
|
119
|
+
## Platform Support (Validated) ✅
|
|
74
120
|
|
|
75
121
|
`Linux`, `macOS`, `Windows`, `WSL`, `FreeBSD`
|
|
76
122
|
|
|
77
123
|
|
|
78
|
-
## Usage
|
|
124
|
+
## Usage 🛠️
|
|
79
125
|
|
|
80
|
-
If you already
|
|
81
|
-
simple as changing your import:
|
|
126
|
+
If you already use the standard library `re`, migration is often just an import swap:
|
|
82
127
|
|
|
83
128
|
```python
|
|
84
129
|
import pcre as re
|
|
85
130
|
```
|
|
86
131
|
|
|
87
|
-
The high-level API
|
|
88
|
-
code can move over with little or no rewriting.
|
|
132
|
+
The high-level API stays close to the standard library, so most existing `re` code can move over with little or no rewriting.
|
|
89
133
|
|
|
90
|
-
### Quick start
|
|
134
|
+
### Quick start 🚀
|
|
91
135
|
|
|
92
136
|
```python
|
|
93
137
|
from pcre import compile, findall, match, search, Flag
|
|
@@ -99,7 +143,7 @@ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
|
|
|
99
143
|
numbers = pattern.findall(b"line 1\nline 22")
|
|
100
144
|
```
|
|
101
145
|
|
|
102
|
-
###
|
|
146
|
+
### API Overview 🧭
|
|
103
147
|
|
|
104
148
|
- Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
|
|
105
149
|
`findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
|
|
@@ -117,7 +161,7 @@ numbers = pattern.findall(b"line 1\nline 22")
|
|
|
117
161
|
- Errors are raised as `pcre.PcreError`; `error` and `PatternError` are kept as
|
|
118
162
|
compatibility aliases.
|
|
119
163
|
|
|
120
|
-
### Common examples
|
|
164
|
+
### Common examples 🧪
|
|
121
165
|
|
|
122
166
|
Compiled patterns:
|
|
123
167
|
|
|
@@ -147,7 +191,7 @@ pattern = compile(br"\w+")
|
|
|
147
191
|
print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
|
|
148
192
|
```
|
|
149
193
|
|
|
150
|
-
### Stdlib `re` compatibility
|
|
194
|
+
### Stdlib `re` compatibility 🔁
|
|
151
195
|
|
|
152
196
|
- Module-level helpers and the `Pattern` class follow the same call shapes as
|
|
153
197
|
the standard library `re` module, including `pos`, `endpos`, and `flags`
|
|
@@ -171,7 +215,7 @@ print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
|
|
|
171
215
|
patterns so escaping semantics remain identical.
|
|
172
216
|
- String patterns enable Unicode behavior by default. Byte patterns do not.
|
|
173
217
|
|
|
174
|
-
### `regex` package compatibility
|
|
218
|
+
### `regex` package compatibility 🔄
|
|
175
219
|
|
|
176
220
|
The [`regex`](https://pypi.org/project/regex/) package interprets
|
|
177
221
|
`\uXXXX` and `\UXXXXXXXX` escapes as UTF-8 code points, while PCRE2 expects
|
|
@@ -189,7 +233,7 @@ Set the default behavior globally with `pcre.configure(compat_regex=True)`
|
|
|
189
233
|
so that subsequent calls to `compile()` and the module-level helpers apply
|
|
190
234
|
the conversion without repeating the flag.
|
|
191
235
|
|
|
192
|
-
### Common issues
|
|
236
|
+
### Common issues ⚠️
|
|
193
237
|
|
|
194
238
|
- Unsupported stdlib flags such as `re.DEBUG`, `re.LOCALE`, and `re.ASCII`
|
|
195
239
|
raise `ValueError`. If you want ASCII-style behavior, use `pcre.ASCII` or
|
|
@@ -201,7 +245,7 @@ the conversion without repeating the flag.
|
|
|
201
245
|
- Most users do not need to tune caching, JIT, or threading. The defaults are
|
|
202
246
|
intended to work well out of the box.
|
|
203
247
|
|
|
204
|
-
### Optional runtime controls
|
|
248
|
+
### Optional runtime controls 🎛️
|
|
205
249
|
|
|
206
250
|
- `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
|
|
207
251
|
`Flag.NO_JIT` let you override that per pattern.
|
|
@@ -211,10 +255,9 @@ the conversion without repeating the flag.
|
|
|
211
255
|
`shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
|
|
212
256
|
if you want to opt into or restrict threaded execution.
|
|
213
257
|
|
|
214
|
-
## Building
|
|
258
|
+
## Building 🏗️
|
|
215
259
|
|
|
216
|
-
The extension links against an existing
|
|
217
|
-
variant). Install the development headers for your platform before building,
|
|
260
|
+
The extension links against an existing `libpcre2-8` installation. Install the development headers for your platform before building,
|
|
218
261
|
for example `apt install libpcre2-dev` on Debian/Ubuntu, `dnf install pcre2-devel`
|
|
219
262
|
on Fedora/RHEL derivatives, or `brew install pcre2` on macOS.
|
|
220
263
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyPcre
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Modern, GIL-friendly, Fast Python bindings for PCRE2 with auto caching and JIT of compiled patterns.
|
|
5
5
|
Author-email: ModelCloud <qubitium@modelcloud.ai>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -27,10 +27,14 @@ Dynamic: license-file
|
|
|
27
27
|
# SPDX-License-Identifier: Apache-2.0
|
|
28
28
|
# Contact: qubitium@modelcloud.ai, x.com/qubitium
|
|
29
29
|
-->
|
|
30
|
+
<div align=center>
|
|
31
|
+
<img width="400" height="1024" alt="image" src="https://github.com/user-attachments/assets/92964c3a-f82e-4949-bd27-278f57c62d9f" />
|
|
32
|
+
</div>
|
|
33
|
+
<h1 align="center">PyPcre (Python PCRE2 Binding) 🧬</h1>
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
<p align=center>
|
|
36
|
+
Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compatible API. ⚡
|
|
37
|
+
</p>
|
|
34
38
|
|
|
35
39
|
<p align="center">
|
|
36
40
|
<a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
|
|
@@ -42,52 +46,92 @@ Modern `nogil` Python bindings for the PCRE2 library with `stdlib.re` API compat
|
|
|
42
46
|
|
|
43
47
|
|
|
44
48
|
|
|
45
|
-
## Latest News
|
|
46
|
-
*
|
|
47
|
-
* 03/
|
|
48
|
-
* 03/
|
|
49
|
-
* 02/
|
|
50
|
-
*
|
|
51
|
-
*
|
|
49
|
+
## Latest News 🚀
|
|
50
|
+
* 04/13/2026 [0.3.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.3.0): Lower-overhead public `Match` objects, faster hot-path `match()` / `search()` / `fullmatch()` / `findall()`, and tighter free-threaded execution. ⚡
|
|
51
|
+
* 03/22/2026 [0.2.15](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.15): Python 3.15 `re` compatibility (`prefixmatch`, `NOFLAG`) ✅
|
|
52
|
+
* 03/21/2026 [0.2.14](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.14): Python 3.14 compatibility 🐍
|
|
53
|
+
* 03/02/2026 [0.2.11](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.11): Auto-detect `Visual Studio` in Windows environments during install and compile. 🪟
|
|
54
|
+
* 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow a `Visual Studio` (VS) compiler version check override via an environment variable. 🧰
|
|
55
|
+
* 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux OS compatibility when both x86_64 and i386 `pcre2` libraries are installed. 🐧
|
|
56
|
+
* 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed the dependency on a system `python3-dev` package. `Python.h` will be downloaded optimistically from python.org when needed. 📦
|
|
52
57
|
* 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance across all APIs. Expanded CI test coverage. FreeBSD, Solaris, and Windows compatibility validated.
|
|
53
58
|
* 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread-safe, with auto JIT, auto pattern caching, and optimistic linking to the system library for fast installs.
|
|
54
59
|
|
|
55
|
-
## Why PyPcre
|
|
60
|
+
## Why PyPcre ⚡
|
|
61
|
+
|
|
62
|
+
PyPcre pairs Python's familiar `re`-compatible API with the real `PCRE2` engine. You keep the ergonomics of the standard library while gaining a more capable regex engine, optional JIT, explicit threading support, and a binding designed and tested for free-threaded Python. 🧠⚡
|
|
63
|
+
|
|
64
|
+
### Big Wins 🏆
|
|
65
|
+
|
|
66
|
+
- 🧬 **Full power of PCRE2**: PyPcre uses the real `PCRE2` engine, so you get native compile options, semantics, JIT, and upstream tuning.
|
|
67
|
+
- 🔥 **More expressive regex syntax**: `PCRE2` supports constructs beyond stdlib `re`, including atomic groups `(?>...)`, possessive quantifiers `++`, branch-reset groups `(?|...)`, richer lookarounds, and backtracking control verbs like `(*SKIP)(*FAIL)`.
|
|
68
|
+
- 🧵 **Thread-safe into `nogil`**: PyPcre is built for `PYTHON_GIL=0`, with CI coverage, lock-aware caches, reusable match/JIT resources, and `parallel_map()` for multi-subject fan-out.
|
|
69
|
+
- ⚡ **Fast on real workloads**: `PCRE2` JIT plus cached compiled patterns lets PyPcre match or beat `re` and `regex` on many common scans, especially multiline searches, lookaround-heavy patterns, and free-threaded execution.
|
|
70
|
+
- 🛡️ **Safer operational story**: PyPcre prefers the system `libpcre2-8` shared library so normal OS package updates can bring security and bug-fix benefits without a bundled fork.
|
|
71
|
+
- ✅ **Validated thoroughly**: the project runs API tests, fuzz tests, memory-safety checks, local `valgrind` leak checks, and `massif` heap profiles. Recent local profiling found `0` definite leaks and `0` possible leaks in both the public API and raw binding paths.
|
|
72
|
+
|
|
73
|
+
### Quick Comparison 🥊
|
|
74
|
+
|
|
75
|
+
| Area | PyPcre | `stdlib.re` | `regex` |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| Engine | Full `PCRE2` ✅ | CPython stdlib engine | Separate engine, not `PCRE2` |
|
|
78
|
+
| `PCRE2` syntax and flags | Full access ✅ | No | No |
|
|
79
|
+
| Syntax power | Very rich ✅ | More limited | Rich, but different from `PCRE2` |
|
|
80
|
+
| JIT execution | `PCRE2` JIT ✅ | No | No |
|
|
81
|
+
| `re`-compatible API surface | Stable and familiar ✅ | Native | Similar, but not the main goal |
|
|
82
|
+
| Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit PyPcre-style layer | Not a project focus here |
|
|
83
|
+
| Built-in threaded subject fan-out | `parallel_map()` ✅ | No | No |
|
|
84
|
+
| System library updates | Uses system `libpcre2-8` by default ✅ | N/A | N/A |
|
|
85
|
+
|
|
86
|
+
### Benchmark Highlights 🏁
|
|
87
|
+
|
|
88
|
+
Measured on a `Python 3.14.3` free-threaded build on x86_64 Linux with compiled-pattern reuse. Times are best-of-5; lower is better.
|
|
89
|
+
|
|
90
|
+
| Workload | Operation | PyPcre | `re` | `regex` | PyPcre edge |
|
|
91
|
+
| --- | --- | ---: | ---: | ---: | --- |
|
|
92
|
+
| First `ERROR` line in a multiline log buffer | `search` | `3.68 ms` | `51.72 ms` | `5.67 ms` | `14.0x` vs `re`, `1.54x` vs `regex` |
|
|
93
|
+
| Extract only `WARN` / `ERROR` lines | `findall` | `6.41 ms` | `91.84 ms` | `91.14 ms` | `14.3x` vs `re`, `14.2x` vs `regex` |
|
|
94
|
+
| Per-line full-name extraction | `findall` | `22.28 ms` | `172.38 ms` | `218.29 ms` | `7.74x` vs `re`, `9.80x` vs `regex` |
|
|
95
|
+
| Lookbehind + negative-lookahead extraction | `findall` | `50.23 ms` | `53.35 ms` | `57.03 ms` | `1.06x` vs `re`, `1.14x` vs `regex` |
|
|
96
|
+
| UUID extraction | `findall` | `77.49 ms` | `83.19 ms` | `134.87 ms` | `1.07x` vs `re`, `1.74x` vs `regex` |
|
|
97
|
+
| Boundary-aware token scan | `findall` | `127.76 ms` | `128.03 ms` | `146.37 ms` | effectively tied with `re`, `1.15x` vs `regex` |
|
|
56
98
|
|
|
57
|
-
|
|
99
|
+
### Free-Threaded Benchmark Highlights 🧵
|
|
58
100
|
|
|
59
|
-
|
|
101
|
+
Measured in the same environment with `8` threads sharing one compiled pattern. Times are best-of-3; lower is better.
|
|
60
102
|
|
|
61
|
-
|
|
103
|
+
| Workload | Threads | PyPcre | `re` | `regex` | PyPcre edge |
|
|
104
|
+
| --- | ---: | ---: | ---: | ---: | --- |
|
|
105
|
+
| First `ERROR` line in a multiline log buffer | `8` | `25.34 ms` | `38.83 ms` | `40.34 ms` | `1.53x` vs `re`, `1.59x` vs `regex` |
|
|
106
|
+
| Extract only `WARN` / `ERROR` lines | `8` | `28.58 ms` | `65.54 ms` | `73.55 ms` | `2.29x` vs `re`, `2.57x` vs `regex` |
|
|
107
|
+
| Per-line full-name extraction | `8` | `31.68 ms` | `123.44 ms` | `164.80 ms` | `3.90x` vs `re`, `5.20x` vs `regex` |
|
|
62
108
|
|
|
63
|
-
|
|
109
|
+
PyPcre is the stronger all-around choice when you want more than the baseline: full `PCRE2` features, more expressive syntax, JIT, explicit free-threaded support, and a stable `re`-compatible API surface. It keeps Python ergonomics while giving you a substantially more capable engine. 🚀
|
|
64
110
|
|
|
65
|
-
## Installation
|
|
111
|
+
## Installation 📦
|
|
66
112
|
|
|
67
113
|
```bash
|
|
68
114
|
pip install PyPcre
|
|
69
115
|
```
|
|
70
116
|
|
|
71
|
-
|
|
117
|
+
By default, the package links against the system `libpcre2-8` shared library for fast installs and to inherit OS security updates. See [Building](#building) for manual build details.
|
|
72
118
|
|
|
73
|
-
## Platform Support (Validated)
|
|
119
|
+
## Platform Support (Validated) ✅
|
|
74
120
|
|
|
75
121
|
`Linux`, `macOS`, `Windows`, `WSL`, `FreeBSD`
|
|
76
122
|
|
|
77
123
|
|
|
78
|
-
## Usage
|
|
124
|
+
## Usage 🛠️
|
|
79
125
|
|
|
80
|
-
If you already
|
|
81
|
-
simple as changing your import:
|
|
126
|
+
If you already use the standard library `re`, migration is often just an import swap:
|
|
82
127
|
|
|
83
128
|
```python
|
|
84
129
|
import pcre as re
|
|
85
130
|
```
|
|
86
131
|
|
|
87
|
-
The high-level API
|
|
88
|
-
code can move over with little or no rewriting.
|
|
132
|
+
The high-level API stays close to the standard library, so most existing `re` code can move over with little or no rewriting.
|
|
89
133
|
|
|
90
|
-
### Quick start
|
|
134
|
+
### Quick start 🚀
|
|
91
135
|
|
|
92
136
|
```python
|
|
93
137
|
from pcre import compile, findall, match, search, Flag
|
|
@@ -99,7 +143,7 @@ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
|
|
|
99
143
|
numbers = pattern.findall(b"line 1\nline 22")
|
|
100
144
|
```
|
|
101
145
|
|
|
102
|
-
###
|
|
146
|
+
### API Overview 🧭
|
|
103
147
|
|
|
104
148
|
- Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
|
|
105
149
|
`findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
|
|
@@ -117,7 +161,7 @@ numbers = pattern.findall(b"line 1\nline 22")
|
|
|
117
161
|
- Errors are raised as `pcre.PcreError`; `error` and `PatternError` are kept as
|
|
118
162
|
compatibility aliases.
|
|
119
163
|
|
|
120
|
-
### Common examples
|
|
164
|
+
### Common examples 🧪
|
|
121
165
|
|
|
122
166
|
Compiled patterns:
|
|
123
167
|
|
|
@@ -147,7 +191,7 @@ pattern = compile(br"\w+")
|
|
|
147
191
|
print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
|
|
148
192
|
```
|
|
149
193
|
|
|
150
|
-
### Stdlib `re` compatibility
|
|
194
|
+
### Stdlib `re` compatibility 🔁
|
|
151
195
|
|
|
152
196
|
- Module-level helpers and the `Pattern` class follow the same call shapes as
|
|
153
197
|
the standard library `re` module, including `pos`, `endpos`, and `flags`
|
|
@@ -171,7 +215,7 @@ print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
|
|
|
171
215
|
patterns so escaping semantics remain identical.
|
|
172
216
|
- String patterns enable Unicode behavior by default. Byte patterns do not.
|
|
173
217
|
|
|
174
|
-
### `regex` package compatibility
|
|
218
|
+
### `regex` package compatibility 🔄
|
|
175
219
|
|
|
176
220
|
The [`regex`](https://pypi.org/project/regex/) package interprets
|
|
177
221
|
`\uXXXX` and `\UXXXXXXXX` escapes as UTF-8 code points, while PCRE2 expects
|
|
@@ -189,7 +233,7 @@ Set the default behavior globally with `pcre.configure(compat_regex=True)`
|
|
|
189
233
|
so that subsequent calls to `compile()` and the module-level helpers apply
|
|
190
234
|
the conversion without repeating the flag.
|
|
191
235
|
|
|
192
|
-
### Common issues
|
|
236
|
+
### Common issues ⚠️
|
|
193
237
|
|
|
194
238
|
- Unsupported stdlib flags such as `re.DEBUG`, `re.LOCALE`, and `re.ASCII`
|
|
195
239
|
raise `ValueError`. If you want ASCII-style behavior, use `pcre.ASCII` or
|
|
@@ -201,7 +245,7 @@ the conversion without repeating the flag.
|
|
|
201
245
|
- Most users do not need to tune caching, JIT, or threading. The defaults are
|
|
202
246
|
intended to work well out of the box.
|
|
203
247
|
|
|
204
|
-
### Optional runtime controls
|
|
248
|
+
### Optional runtime controls 🎛️
|
|
205
249
|
|
|
206
250
|
- `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
|
|
207
251
|
`Flag.NO_JIT` let you override that per pattern.
|
|
@@ -211,10 +255,9 @@ the conversion without repeating the flag.
|
|
|
211
255
|
`shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
|
|
212
256
|
if you want to opt into or restrict threaded execution.
|
|
213
257
|
|
|
214
|
-
## Building
|
|
258
|
+
## Building 🏗️
|
|
215
259
|
|
|
216
|
-
The extension links against an existing
|
|
217
|
-
variant). Install the development headers for your platform before building,
|
|
260
|
+
The extension links against an existing `libpcre2-8` installation. Install the development headers for your platform before building,
|
|
218
261
|
for example `apt install libpcre2-dev` on Debian/Ubuntu, `dnf install pcre2-devel`
|
|
219
262
|
on Fedora/RHEL derivatives, or `brew install pcre2` on macOS.
|
|
220
263
|
|
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
# SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
# Contact: qubitium@modelcloud.ai, x.com/qubitium
|
|
6
6
|
-->
|
|
7
|
+
<div align=center>
|
|
8
|
+
<img width="400" height="1024" alt="image" src="https://github.com/user-attachments/assets/92964c3a-f82e-4949-bd27-278f57c62d9f" />
|
|
9
|
+
</div>
|
|
10
|
+
<h1 align="center">PyPcre (Python PCRE2 Binding) 🧬</h1>
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
<p align=center>
|
|
13
|
+
Fast, free-threaded Python bindings for `PCRE2` with a stable `stdlib.re`-compatible API. ⚡
|
|
14
|
+
</p>
|
|
11
15
|
|
|
12
16
|
<p align="center">
|
|
13
17
|
<a href="https://github.com/ModelCloud/PyPcre/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/Pcre.svg"></a>
|
|
@@ -19,52 +23,92 @@ Modern `nogil` Python bindings for the PCRE2 library with `stdlib.re` API compat
|
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
|
|
22
|
-
## Latest News
|
|
23
|
-
*
|
|
24
|
-
* 03/
|
|
25
|
-
* 03/
|
|
26
|
-
* 02/
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
## Latest News 🚀
|
|
27
|
+
* 04/13/2026 [0.3.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.3.0): Lower-overhead public `Match` objects, faster hot-path `match()` / `search()` / `fullmatch()` / `findall()`, and tighter free-threaded execution. ⚡
|
|
28
|
+
* 03/22/2026 [0.2.15](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.15): Python 3.15 `re` compatibility (`prefixmatch`, `NOFLAG`) ✅
|
|
29
|
+
* 03/21/2026 [0.2.14](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.14): Python 3.14 compatibility 🐍
|
|
30
|
+
* 03/02/2026 [0.2.11](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.11): Auto-detect `Visual Studio` in Windows environments during install and compile. 🪟
|
|
31
|
+
* 02/24/2026 [0.2.10](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.10): Allow a `Visual Studio` (VS) compiler version check override via an environment variable. 🧰
|
|
32
|
+
* 12/15/2025 [0.2.8](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.8): Fixed multi-arch Linux OS compatibility when both x86_64 and i386 `pcre2` libraries are installed. 🐧
|
|
33
|
+
* 10/20/2025 [0.2.4](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.4): Removed the dependency on a system `python3-dev` package. `Python.h` will be downloaded optimistically from python.org when needed. 📦
|
|
29
34
|
* 10/12/2025 [0.2.3](https://github.com/ModelCloud/PyPcre/releases/tag/v0.2.3): 🤗 Full `GIL=0` compliance for Python >= 3.13T. Reduced cache thread contention. Improved performance across all APIs. Expanded CI test coverage. FreeBSD, Solaris, and Windows compatibility validated.
|
|
30
35
|
* 10/09/2025 [0.1.0](https://github.com/ModelCloud/PyPcre/releases/tag/v0.1.0): 🎉 First release. Thread-safe, with auto JIT, auto pattern caching, and optimistic linking to the system library for fast installs.
|
|
31
36
|
|
|
32
|
-
## Why PyPcre
|
|
37
|
+
## Why PyPcre ⚡
|
|
38
|
+
|
|
39
|
+
PyPcre pairs Python's familiar `re`-compatible API with the real `PCRE2` engine. You keep the ergonomics of the standard library while gaining a more capable regex engine, optional JIT, explicit threading support, and a binding designed and tested for free-threaded Python. 🧠⚡
|
|
40
|
+
|
|
41
|
+
### Big Wins 🏆
|
|
42
|
+
|
|
43
|
+
- 🧬 **Full power of PCRE2**: PyPcre uses the real `PCRE2` engine, so you get native compile options, semantics, JIT, and upstream tuning.
|
|
44
|
+
- 🔥 **More expressive regex syntax**: `PCRE2` supports constructs beyond stdlib `re`, including atomic groups `(?>...)`, possessive quantifiers `++`, branch-reset groups `(?|...)`, richer lookarounds, and backtracking control verbs like `(*SKIP)(*FAIL)`.
|
|
45
|
+
- 🧵 **Thread-safe into `nogil`**: PyPcre is built for `PYTHON_GIL=0`, with CI coverage, lock-aware caches, reusable match/JIT resources, and `parallel_map()` for multi-subject fan-out.
|
|
46
|
+
- ⚡ **Fast on real workloads**: `PCRE2` JIT plus cached compiled patterns lets PyPcre match or beat `re` and `regex` on many common scans, especially multiline searches, lookaround-heavy patterns, and free-threaded execution.
|
|
47
|
+
- 🛡️ **Safer operational story**: PyPcre prefers the system `libpcre2-8` shared library so normal OS package updates can bring security and bug-fix benefits without a bundled fork.
|
|
48
|
+
- ✅ **Validated thoroughly**: the project runs API tests, fuzz tests, memory-safety checks, local `valgrind` leak checks, and `massif` heap profiles. Recent local profiling found `0` definite leaks and `0` possible leaks in both the public API and raw binding paths.
|
|
49
|
+
|
|
50
|
+
### Quick Comparison 🥊
|
|
51
|
+
|
|
52
|
+
| Area | PyPcre | `stdlib.re` | `regex` |
|
|
53
|
+
| --- | --- | --- | --- |
|
|
54
|
+
| Engine | Full `PCRE2` ✅ | CPython stdlib engine | Separate engine, not `PCRE2` |
|
|
55
|
+
| `PCRE2` syntax and flags | Full access ✅ | No | No |
|
|
56
|
+
| Syntax power | Very rich ✅ | More limited | Rich, but different from `PCRE2` |
|
|
57
|
+
| JIT execution | `PCRE2` JIT ✅ | No | No |
|
|
58
|
+
| `re`-compatible API surface | Stable and familiar ✅ | Native | Similar, but not the main goal |
|
|
59
|
+
| Free-threaded support | Built and tested for `PYTHON_GIL=0` ✅ | No explicit PyPcre-style layer | Not a project focus here |
|
|
60
|
+
| Built-in threaded subject fan-out | `parallel_map()` ✅ | No | No |
|
|
61
|
+
| System library updates | Uses system `libpcre2-8` by default ✅ | N/A | N/A |
|
|
62
|
+
|
|
63
|
+
### Benchmark Highlights 🏁
|
|
64
|
+
|
|
65
|
+
Measured on a `Python 3.14.3` free-threaded build on x86_64 Linux with compiled-pattern reuse. Times are best-of-5; lower is better.
|
|
66
|
+
|
|
67
|
+
| Workload | Operation | PyPcre | `re` | `regex` | PyPcre edge |
|
|
68
|
+
| --- | --- | ---: | ---: | ---: | --- |
|
|
69
|
+
| First `ERROR` line in a multiline log buffer | `search` | `3.68 ms` | `51.72 ms` | `5.67 ms` | `14.0x` vs `re`, `1.54x` vs `regex` |
|
|
70
|
+
| Extract only `WARN` / `ERROR` lines | `findall` | `6.41 ms` | `91.84 ms` | `91.14 ms` | `14.3x` vs `re`, `14.2x` vs `regex` |
|
|
71
|
+
| Per-line full-name extraction | `findall` | `22.28 ms` | `172.38 ms` | `218.29 ms` | `7.74x` vs `re`, `9.80x` vs `regex` |
|
|
72
|
+
| Lookbehind + negative-lookahead extraction | `findall` | `50.23 ms` | `53.35 ms` | `57.03 ms` | `1.06x` vs `re`, `1.14x` vs `regex` |
|
|
73
|
+
| UUID extraction | `findall` | `77.49 ms` | `83.19 ms` | `134.87 ms` | `1.07x` vs `re`, `1.74x` vs `regex` |
|
|
74
|
+
| Boundary-aware token scan | `findall` | `127.76 ms` | `128.03 ms` | `146.37 ms` | effectively tied with `re`, `1.15x` vs `regex` |
|
|
33
75
|
|
|
34
|
-
|
|
76
|
+
### Free-Threaded Benchmark Highlights 🧵
|
|
35
77
|
|
|
36
|
-
|
|
78
|
+
Measured in the same environment with `8` threads sharing one compiled pattern. Times are best-of-3; lower is better.
|
|
37
79
|
|
|
38
|
-
|
|
80
|
+
| Workload | Threads | PyPcre | `re` | `regex` | PyPcre edge |
|
|
81
|
+
| --- | ---: | ---: | ---: | ---: | --- |
|
|
82
|
+
| First `ERROR` line in a multiline log buffer | `8` | `25.34 ms` | `38.83 ms` | `40.34 ms` | `1.53x` vs `re`, `1.59x` vs `regex` |
|
|
83
|
+
| Extract only `WARN` / `ERROR` lines | `8` | `28.58 ms` | `65.54 ms` | `73.55 ms` | `2.29x` vs `re`, `2.57x` vs `regex` |
|
|
84
|
+
| Per-line full-name extraction | `8` | `31.68 ms` | `123.44 ms` | `164.80 ms` | `3.90x` vs `re`, `5.20x` vs `regex` |
|
|
39
85
|
|
|
40
|
-
|
|
86
|
+
PyPcre is the stronger all-around choice when you want more than the baseline: full `PCRE2` features, more expressive syntax, JIT, explicit free-threaded support, and a stable `re`-compatible API surface. It keeps Python ergonomics while giving you a substantially more capable engine. 🚀
|
|
41
87
|
|
|
42
|
-
## Installation
|
|
88
|
+
## Installation 📦
|
|
43
89
|
|
|
44
90
|
```bash
|
|
45
91
|
pip install PyPcre
|
|
46
92
|
```
|
|
47
93
|
|
|
48
|
-
|
|
94
|
+
By default, the package links against the system `libpcre2-8` shared library for fast installs and to inherit OS security updates. See [Building](#building) for manual build details.
|
|
49
95
|
|
|
50
|
-
## Platform Support (Validated)
|
|
96
|
+
## Platform Support (Validated) ✅
|
|
51
97
|
|
|
52
98
|
`Linux`, `macOS`, `Windows`, `WSL`, `FreeBSD`
|
|
53
99
|
|
|
54
100
|
|
|
55
|
-
## Usage
|
|
101
|
+
## Usage 🛠️
|
|
56
102
|
|
|
57
|
-
If you already
|
|
58
|
-
simple as changing your import:
|
|
103
|
+
If you already use the standard library `re`, migration is often just an import swap:
|
|
59
104
|
|
|
60
105
|
```python
|
|
61
106
|
import pcre as re
|
|
62
107
|
```
|
|
63
108
|
|
|
64
|
-
The high-level API
|
|
65
|
-
code can move over with little or no rewriting.
|
|
109
|
+
The high-level API stays close to the standard library, so most existing `re` code can move over with little or no rewriting.
|
|
66
110
|
|
|
67
|
-
### Quick start
|
|
111
|
+
### Quick start 🚀
|
|
68
112
|
|
|
69
113
|
```python
|
|
70
114
|
from pcre import compile, findall, match, search, Flag
|
|
@@ -76,7 +120,7 @@ pattern = compile(rb"\d+", flags=Flag.MULTILINE)
|
|
|
76
120
|
numbers = pattern.findall(b"line 1\nline 22")
|
|
77
121
|
```
|
|
78
122
|
|
|
79
|
-
###
|
|
123
|
+
### API Overview 🧭
|
|
80
124
|
|
|
81
125
|
- Module helpers: `prefixmatch`, `match`, `search`, `fullmatch`, `finditer`,
|
|
82
126
|
`findall`, `split`, `sub`, `subn`, `compile`, `escape`, `purge`, and
|
|
@@ -94,7 +138,7 @@ numbers = pattern.findall(b"line 1\nline 22")
|
|
|
94
138
|
- Errors are raised as `pcre.PcreError`; `error` and `PatternError` are kept as
|
|
95
139
|
compatibility aliases.
|
|
96
140
|
|
|
97
|
-
### Common examples
|
|
141
|
+
### Common examples 🧪
|
|
98
142
|
|
|
99
143
|
Compiled patterns:
|
|
100
144
|
|
|
@@ -124,7 +168,7 @@ pattern = compile(br"\w+")
|
|
|
124
168
|
print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
|
|
125
169
|
```
|
|
126
170
|
|
|
127
|
-
### Stdlib `re` compatibility
|
|
171
|
+
### Stdlib `re` compatibility 🔁
|
|
128
172
|
|
|
129
173
|
- Module-level helpers and the `Pattern` class follow the same call shapes as
|
|
130
174
|
the standard library `re` module, including `pos`, `endpos`, and `flags`
|
|
@@ -148,7 +192,7 @@ print(pattern.findall(b"ab cd")) # [b'ab', b'cd']
|
|
|
148
192
|
patterns so escaping semantics remain identical.
|
|
149
193
|
- String patterns enable Unicode behavior by default. Byte patterns do not.
|
|
150
194
|
|
|
151
|
-
### `regex` package compatibility
|
|
195
|
+
### `regex` package compatibility 🔄
|
|
152
196
|
|
|
153
197
|
The [`regex`](https://pypi.org/project/regex/) package interprets
|
|
154
198
|
`\uXXXX` and `\UXXXXXXXX` escapes as UTF-8 code points, while PCRE2 expects
|
|
@@ -166,7 +210,7 @@ Set the default behavior globally with `pcre.configure(compat_regex=True)`
|
|
|
166
210
|
so that subsequent calls to `compile()` and the module-level helpers apply
|
|
167
211
|
the conversion without repeating the flag.
|
|
168
212
|
|
|
169
|
-
### Common issues
|
|
213
|
+
### Common issues ⚠️
|
|
170
214
|
|
|
171
215
|
- Unsupported stdlib flags such as `re.DEBUG`, `re.LOCALE`, and `re.ASCII`
|
|
172
216
|
raise `ValueError`. If you want ASCII-style behavior, use `pcre.ASCII` or
|
|
@@ -178,7 +222,7 @@ the conversion without repeating the flag.
|
|
|
178
222
|
- Most users do not need to tune caching, JIT, or threading. The defaults are
|
|
179
223
|
intended to work well out of the box.
|
|
180
224
|
|
|
181
|
-
### Optional runtime controls
|
|
225
|
+
### Optional runtime controls 🎛️
|
|
182
226
|
|
|
183
227
|
- `pcre.configure(jit=False)` disables JIT globally. `Flag.JIT` and
|
|
184
228
|
`Flag.NO_JIT` let you override that per pattern.
|
|
@@ -188,10 +232,9 @@ the conversion without repeating the flag.
|
|
|
188
232
|
`shutdown_thread_pool()`, `Flag.THREADS`, and `Flag.NO_THREADS` are available
|
|
189
233
|
if you want to opt into or restrict threaded execution.
|
|
190
234
|
|
|
191
|
-
## Building
|
|
235
|
+
## Building 🏗️
|
|
192
236
|
|
|
193
|
-
The extension links against an existing
|
|
194
|
-
variant). Install the development headers for your platform before building,
|
|
237
|
+
The extension links against an existing `libpcre2-8` installation. Install the development headers for your platform before building,
|
|
195
238
|
for example `apt install libpcre2-dev` on Debian/Ubuntu, `dnf install pcre2-devel`
|
|
196
239
|
on Fedora/RHEL derivatives, or `brew install pcre2` on macOS.
|
|
197
240
|
|