Skip to main content

pyRegTab: pattern-based extraction of recordsets from tables (RTL / ATP / ITM)

Project description

pyRegTab

RegTab: pattern-driven data extraction from document tables with regular structure — the Python port of jRegTab with a native Rust core.

pyRegTab compiles RTL (Regular Table Language) patterns into abstract table patterns (ATP), matches them against a table's syntactic layer (ITM), and interprets the match into a relational recordset:

TableSyntax → RtlCompiler/TablePattern → AtpMatcher → TableInterpreter → Recordset

pyRegTab 0.1.x ≙ jRegTab 0.3.0 (same API, same semantics, same test corpus).

Installation

pip install pyregtab

Binary wheels are published for Windows, Linux and macOS (x86-64 / arm64), CPython ≥ 3.10 (one abi3 wheel per platform). Building from the sdist requires a Rust toolchain.

Example

from pyregtab import TableSyntax, RtlCompiler, AtpMatcher, TableInterpreter

syntax = TableSyntax(3, 3)
syntax.cell(0, 1).set_text("CA");  syntax.cell(0, 2).set_text("HU")
syntax.cell(1, 0).set_text("IKT"); syntax.cell(1, 1).set_text("0 Jan"); syntax.cell(1, 2).set_text("8 Feb")
syntax.cell(2, 0).set_text("SVO"); syntax.cell(2, 1).set_text("31 Jan"); syntax.cell(2, 2).set_text("40 Feb")

pattern = RtlCompiler.compile("""
    [ [] [VAL : 'AIRLINE'->AVP]+ ]
    [ [VAL : 'AIRPORT'->AVP]
      [VAL : (COL, ROW, CL)->REC, 'ND'->AVP " " VAL : 'MON'->AVP]+ ]+
""")

itm = AtpMatcher.match(pattern, syntax)     # InterpretableTable | None
rs = TableInterpreter().interpret(itm)      # Recordset
rs.schema.attributes                        # ['ND', 'AIRLINE', 'AIRPORT', 'MON']
rs[0]["ND"]                                 # '0'
df = rs.to_pandas()                         # extras: pip install pyregtab[pandas]

Patterns can also be built without RTL, via the fluent spec API (TablePattern.of(SubtablePattern.of(...)) — same factories as in Java, snake_case method names), and serialized back to RTL with AtpToRtlSerializer.serialize(pattern).

Named Python predicates are attached to RTL via EXT('name'):

from pyregtab import Bindings

p = RtlCompiler.compile(
    "{ [ [EXT('isTotal') ? VAL : ST*->REC] []+ ] }+",
    Bindings.of().cell("isTotal", lambda cell: cell.text.startswith("Total")),
)

API mapping (Java → Python)

Java Python
RtlCompiler.compile(String) RtlCompiler.compile(str) / pyregtab.compile(...)
AtpMatcher.match(p, s)Optional<InterpretableTable> AtpMatcher.match(p, s)InterpretableTable | None
Quantifier.oneOrMore() Quantifier.one_or_more()
new TableInterpreter().withStrategy(s).interpret(itm) TableInterpreter().with_strategy(s).interpret(itm)
rs.records().get(0).get("Name") rs[0]["Name"], rs.records, record.get("Name")
cell.text() / cell.setText(t) property cell.text (get/set); cell.set_text(t) also works
RtlCompileException RtlCompileError

Architecture

Everything after the Python call boundary runs in a native core written in Rust (pyregtab._core, built with PyO3 and maturin); the Python layer is a thin re-export.

  • grammar/RTL.g4 — the normative specification of the RTL language (a pinned copy from jRegTab; the upstream commit is recorded in grammar/UPSTREAM). The core's parser is a hand-written lexer + recursive descent that structurally follows the grammar rules.
  • conformance/ — the shared RTL conformance corpus (also pinned from jRegTab, see conformance/UPSTREAM and conformance/README.md). Both implementations must compile every positive case to the same canonical form and reject every negative case; the corpus runs in CI of both projects. Any RTL language change flows: RTL.g4 in jregtab → corpus extension → both parsers → green corpus in both CIs.
  • Regular expressions in RTL constraints are executed by the Rust regex crate (linear-time). The reference fixture corpus uses no lookaround/backreferences (audited), so the dialect is compatible with java.util.regex on this corpus. Documented divergences from Java: \d/\s/\w are Unicode-aware in regex (ASCII in Java), and SUBSTR indices count code points (UTF-16 units in Java) — identical behavior on the entire reference corpus.

Testing

pytest tests runs (1 878 tests):

  • the full benchmark suite — tasks 001–150 (Foofah, RegTab, Baikal), every fixture variant, both via RTL patterns and via ATP patterns built with the Python spec API (1 500 task variants in total; fixtures are copied verbatim from jRegTab into tests/fixtures/tasks, ATP builders are mechanically translated from the Java tests by tools/translate_atp.py);
  • the RTL conformance corpus (positive canonical forms, fixed points, negative rejections);
  • RTL↔ATP round-trip for tasks 001–050;
  • API unit tests (syntax layer, extractors, EXT bindings, custom predicates, transformations, interpreter options, GIL-released batch matching from a thread pool).

cargo test additionally runs the conformance corpus and an end-to-end smoke test against the native core alone. Differential testing against the Java reference (tools/differential.py + tools/RecordsetDumpMain.java) compares recordsets cell-by-cell on all 750 task variants — zero mismatches against jRegTab v0.3.0.

Development

python -m venv .venv && . .venv/bin/activate   # or .venv\Scripts\activate
pip install maturin pytest
maturin develop --release
pytest tests -q

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyregtab-0.1.0-cp310-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

pyregtab-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

pyregtab-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

pyregtab-0.1.0-cp310-abi3-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

pyregtab-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file pyregtab-0.1.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: pyregtab-0.1.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.14.1

File hashes

Hashes for pyregtab-0.1.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 e6f041695e02a1b3d266cbee7eb694eb5204b99db44aa626c287d3a606523dca
MD5 34cebf75612984acaa9fa1b8201b82b4
BLAKE2b-256 0707aff5d70d67bb85202b1be68241330804112b1133923211d01cdb90517a14

See more details on using hashes here.

File details

Details for the file pyregtab-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyregtab-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e8d0af08af8084f017173593daf7fb165b572898f1500d6d4ecb3a88f09ca30d
MD5 ac543ef72ded23676ebabc1fb57bcc8d
BLAKE2b-256 23b94bf8aee13512cc8d2b2c22e5a5d9a98243d34c03c9954e8101ac7b4ba89c

See more details on using hashes here.

File details

Details for the file pyregtab-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyregtab-0.1.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c9a2ecb5c3af13f397558a6345aa1fdc5afa7f7a0b2e8fa0a8cc6030847014be
MD5 f0f71cdf3fa347e0d9817244f9c55b34
BLAKE2b-256 2cedeb883cc07a340dae9f7cd23400ae1b9121b1e33e25e5d016e2c1ace1645f

See more details on using hashes here.

File details

Details for the file pyregtab-0.1.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pyregtab-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1b6ffcbbea41fb985815cb575c55ae527d3dccc32b79c584b1c35f47ab7452eb
MD5 229b8b88eec3000ea39be454aeab794d
BLAKE2b-256 827875fab13a4e68a3d90a4f43bb413acbf1303af23c21cff7b1d64bce4d1bfd

See more details on using hashes here.

File details

Details for the file pyregtab-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pyregtab-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f9faa1cf460c18c8e68bb058fbf797a2fdcf5273a3aab6cbceb1ca7d7b61cfa6
MD5 3ea774db6e407b5eb836298cb6b697ff
BLAKE2b-256 7f0dfb7f2fed34cdc7085c088468f250cc7802d29d91e9b339cb472b93eabd97

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page