API reference
The public Python API of pyRegTab mirrors the jRegTab (Java) API 1:1 in classes
and semantics; method names follow PEP 8 (snake_case). Everything is exported
from the top-level pyregtab package; the implementation lives in the native
core pyregtab._core (Rust). Full signatures are in the bundled type stubs
(pyregtab/_core.pyi).
Pipeline entry points
| Class / function | Role |
|---|---|
RtlCompiler.compile(rtl, bindings=None) / pyregtab.compile(...) |
RTL string → TablePattern; raises RtlCompileError with source position (.line 1-based, .col 0-based, both None when unknown) |
AtpMatcher.match(pattern, syntax, context_items=None) |
TablePattern × TableSyntax → InterpretableTable \| None |
AtpMatcher.match_many(pattern, syntaxes, context_items=None) |
batch form of match: list[InterpretableTable \| None] in input order, matched in parallel on an internal thread pool (GIL released) |
TableInterpreter().interpret(itm) |
InterpretableTable → Recordset |
AtpToRtlSerializer.serialize(pattern) |
TablePattern → canonical RTL string |
TablePattern.transform(rs) |
applies the pattern's recordset transformations |
TableInterpreter is configured fluently:
rs = (
TableInterpreter()
.with_strategy(SchemaConstructionStrategy.RECORD_FIRST) # or POSITION_FIRST
.with_action_application_strategy(ActionApplicationStrategy.ROW_FIRST)
.with_missing_value_handler(lambda attr: "") # str -> str | None
.with_anonymous_attribute_template("A%i") # default "$a_%i"
.with_strict_preconditions(False) # default: skipped CONCAT/JOIN actions are reported, not raised
.interpret(itm)
)
After interpret, TableInterpreter.diagnostics() lists the CONCAT/JOIN actions that
had no effect (as Diagnostic objects with .anchor, .operation, .message): a key
mismatch, a named attribute shared by two concatenated records, an empty record product, and
— for actions written on the anchor's own content spec, not inherited — an anchor without a
record (anchor has no record — REC missing?) or provided items none of which has a record.
With with_strict_preconditions(True) the first such case raises a RuntimeError instead.
When the pattern contains no Python callbacks (no EXT/custom predicates),
AtpMatcher.match and TableInterpreter.interpret release the GIL — batch
processing parallelizes with a plain ThreadPoolExecutor, or use
AtpMatcher.match_many, which fans the tables out over an internal thread
pool itself. With Python callbacks present, match_many degrades to matching
sequentially under the GIL, like match.
ITM: syntactic layer
| Class | Notes |
|---|---|
TableSyntax(num_rows, num_cols) |
grid of pre-created cells; cell(r, c), row(i), rows(), subtables(), all_cells(), define_subtables(*starts), define_subrow(row, c0, c1) |
TableSyntax.from_rows(rows, *, num_cols=None) |
the grid from rows of cell texts in one call (num_cols defaults to the widest row; shorter rows are padded with empty cells) |
TableSyntax.from_csv(path), TableSyntax.from_csv_text(text) |
the grid from a CSV file (UTF-8, universal newlines) or text with the CLI runner's rules — RFC 4180 (quoted fields may hold commas, doubled quotes and line breaks), empty lines skipped, ragged rows padded; pyregtab.runner.parse_csv(text) returns the parsed rows |
Cell |
properties: text (get/set, plus set_text()), text_blank, text_multiline, text_indent, row, col, pos, bbox, merged, formatting (font_*, horz_align, vert_align, borders, bg_color, fg_color, rotation), structure (parent_row, subtable, subrow) |
Row, Subrow, Subtable |
structural handles (subrows(), cells(), rows()) |
GridPosition, BoundingBox, CellColor |
value types; enums FontFamily, HorizontalAlignment, VerticalAlignment |
ITM: semantic layer and result
| Class | Notes |
|---|---|
InterpretableTable |
.syntax, .semantics |
TableSemantics |
cell_derived_items(), context_derived_items() |
CellDerivedItem |
.str, .tags, .index, .cell, .span (byte range of the item's source segment within the raw cell text, before extractors); passed to filter callbacks |
ContextDerivedItem(s, ItemType, const_value=None) |
external context items for AtpMatcher.match |
Recordset |
.schema, .records, len(rs), rs[i], to_pandas(), to_csv(path=None, sep=",", missing="", quote_all=False, newline="\r\n") (RFC 4180; returns the CSV text when path is None, otherwise streams the records into the file) |
Record |
rec[attr], rec[i], .get(...), .values(); missing value → None |
Schema |
.attributes, index_of, contains |
ATP: pattern specification
Pattern hierarchy — each level has of(...) factories accepting an optional
leading CellMatchCondition and/or Quantifier, canonical constructors, and
postfix quantifier copies (one_or_more(), zero_or_more(), zero_or_one(),
exactly(n)):
TablePattern.of(*subtables) → SubtablePattern.of(*rows) →
RowPattern.of(*cells_or_subrows) → SubrowPattern.of(*cells) →
CellPattern.of(content_spec) / CellPattern.skip().
Content specifications:
| Class | RTL analog |
|---|---|
AtomicContentSpec.val/attr/aux(*actions, extractor=None), .skip(), .val_tagged(tag, *actions) |
VAL : … |
DelimitedContentSpec(delim, atom) / atom.split_by(delim) |
(VAL){","} |
CompoundContentSpec.of(first, (delim, spec), ...) / spec.then(delim, next) |
VAL " " VAL |
ConditionalContentSpec(cond, positive, negative) |
BLANK? _ \| VAL |
Actions and providers:
| Factory | RTL analog |
|---|---|
ActionSpec.rec(*providers, anchor_pos=None, split_delimiter=None) |
…->REC, REC(n), REC('/') |
ActionSpec.avp(provider_or_str) |
…->AVP, 'NAME'->AVP |
ActionSpec.concat(*providers, key=None) |
…->CONCAT, CONCAT(k…), CONCAT('A'), CONCAT(0, 'A') — fold the provided records into the anchor's record; key is an int, a str, an iterable of both, or a RecordKey (key_positions= is kept for 0.5.x callers) |
ActionSpec.join(*providers, key=None) |
…->JOIN, JOIN(k…), JOIN('A') — the record product (equi-join on key) |
RecordKey(positions=(), names=()), RecordKey.of(…), RecordKey.empty(); ActionSpec.key / .key_positions |
the key K of a CONCAT/JOIN action |
ActionSpec.fill/prefix/suffix(delimiter, *providers) |
…->FILL("d") |
ProviderSpec.val/attr/aux/any(condition, cardinality=1, traversal_order=None) |
ST*, -AV, ^COL{2} |
ProviderSpec.ctx_attr/ctx_val/ctx_aux(text), ctx_avp(name, value) |
'NAME', @'A'='V' |
Conditions and predicates:
| Factory | RTL analog |
|---|---|
CellMatchCondition(CellPredicate.blank() / not_blank() / regex_matched(p) / contains(s) / external(name, fn) / custom(desc, fn)) |
BLANK?, "re"?, ~"s"?, EXT('name')? |
ItemFilterConditionSpec.bare(term), .and_(*terms), .or_(*groups), shorthands same_subtable() … left_of() |
(LT & !BLANK) |
FilterTerm.* — spatial (left_of … same_cell, col_exact, row_offset, pos_range, …) and content (regex_matched, contains, blank, tagged, same_str, external, custom) |
spatConstr / contConstr |
StringExtractor.whitespace_normalized() / trimmed() / upper_case() / lower_case() / substring(b, e) / replaced(rx, rep) / chain(*steps) / custom(desc, fn) |
=NORM, =TRIM, … |
Quantifier.one() / zero_or_one() / one_or_more() / zero_or_more() / exactly(n) |
?, +, *, {n} (n ≥ 0; {1} ≡ no quantifier, {0} ≡ empty match) |
Custom (custom) and external (EXT) predicates take Python callables:
cell predicates receive a Cell, item filters receive
(anchor: CellDerivedItem, candidate: CellDerivedItem). Patterns with custom
predicates cannot be serialized back to RTL (as in Java) and disable the
GIL-release fast path.
Embedded RTL DSL
pyregtab.dsl is a fluent, RTL-like layer over the ATP factories above:
table/subtable/row/subrow/cell, atoms val/attr/aux, actions rec/avp/join/
fill/prefix/suffix, provider constants (ST, COL, C(n), …) with
.and_()/.or_()/.card()/.unbounded() and traversal methods, and where(...)
Python-callable escape hatches. It builds ordinary TablePattern objects,
byte-identical to RtlCompiler.compile for lambda-free patterns. See the
Embedded RTL guide.
Recordset transformations
WhitespaceNormalization(), AnchorAttributeAtPosition(pos),
DelimitedFieldSplit(delim, only_attributes=None, anonymous_attribute_template="$a_%i"),
FieldSplitting(attribute, delimiter, part_attribute_names=()),
SchemaReordering(order) — each has .apply(recordset); attach to a pattern
with pattern.with_transformations(...) or to an interpreter with
.with_transformations([...]). RTL settings <NORM, ANCH(n), SPLIT("s")> and
inline REC(n) / REC('s') parameters compile to these transformations.
AnchorAttributeAtPosition(pos) moves the anchor attribute — its name together with
its values — to 0-based position pos; it renames nothing, so every attribute-value
binding survives and only the schema order changes.
RTL bindings
bindings = (
Bindings.of()
.cell("isTotal", lambda cell: cell.text.startswith("Total")) # EXT in cell-condition position
.filter("near", lambda a, c: abs(a.cell.row - c.cell.row) <= 2) # EXT in provider position
)
pattern = RtlCompiler.compile(rtl, bindings)
Unbound EXT('name') references raise RtlCompileError at compile time with
the position of the constraint.