MatchData: An Ergonomic, Parsed Regex Match#

class my.regex.MatchData.MatchData(*, data: dict[str, list[str]]={}, duplicates: bool = True, overwrite: bool = False, match: Match, ~pydantic.types.GetPydanticSchema(get_pydantic_core_schema=~my.utils.SyntaxUtils.SyntaxUtils.pyd_schemify.<locals>.<lambda>, get_pydantic_json_schema=None)] | None = None)#

Ergonomic container for regex search results, especially those with repeated groups.

Extends Predicate to STORE captured group values while also maintaining a reference to the original match object for accessing spans, positions, and matched text.

Provides cached properties for common match attributes like start, end, and text.

Examples

Wrap a match and access its repeated captures ergonomically:

>>> import regex as re
>>> data = MatchData(match=re.fullmatch(r'(?:(?P<w>\w+) ?)+', 'ab cd'))
>>> data['w']
['ab', 'cd']
>>> data.at('w')
'cd'
>>> data.text, data.start, data.end
('ab cd', 0, 5)

Empty results are falsy, so lookups chain cleanly:

>>> bool(MatchData())
False

I Initial Methods#

classmethod MatchData.new(*args: Any, match: Match | None = None, **kwargs: Any) → Self#

Construct a new MatchData, coercing mapping-like arguments and binding a source match.

Duplicates are always enabled so repeated capture groups accumulate their values; empty group names and empty value lists are dropped.

Parameters:
  • *args – Mapping-like objects to merge into the captured group data.

  • match – Original regex match object, retained for span/position/text access.

  • **kwargs – Additional group values to merge.

Returns:

New MatchData holding the merged group data.

Examples

Merge mapping-like arguments, accumulating repeated keys:

>>> from my import MatchData
>>> MatchData.new(dict(k=['v1']), k='v2')
MatchData({'k': ['v1', 'v2']})

Bind a source match to expose its captures, spans, and text:

>>> import regex as re
>>> MatchData.new(match=re.fullmatch(r'(?:(?P<word>\w+) ?)+', 'one two three'))
MatchData("one two three" -> {'word': ['one', 'two', 'three']})

II Primary Methods#

property MatchData.flat: dict[str, str]#

A flat dictionary of the last non-empty value for each group.

Examples

Flatten repeated captures down to their final values:

>>> import regex as re
>>> from my import MatchData
>>> data = MatchData(match=re.fullmatch(r'(?:(?P<word>\w+) ?)+', 'one two three'))
>>> data['word']
['one', 'two', 'three']
>>> data.flat
{'word': 'three'}
>>> (data.text, data.span, data.size)
('one two three', Span(0, 13), 13)
property MatchData.span: Span#

The span of the match if present; otherwise the null span (0, 0).

property MatchData.start: int#

The start index of the match if present; otherwise 0.

property MatchData.end: int#

The end index of the match if present; otherwise 0.

property MatchData.text: str#

The text of the match if present; otherwise an empty string.

property MatchData.size: int#

The number of characters matched.

III Public Methods#

MatchData.print(indent: str = '') → None#

Print captured groups in a formatted table.

Parameters:

indent – String to prepend to each line for indentation.

Examples

Repeated captures print as lists, single captures as scalars:

>>> import regex as re
>>> from my import MatchData
>>> data = MatchData(match=re.fullmatch(r'(?:(?P<word>\w+) ?)+', 'one two three'))
>>> data.print(indent='  ')
  word: ['one', 'two', 'three']
MatchData.set_to(other: MatchData | None) → None#

Replace this MatchData’s contents with another’s, clearing caches.

Parameters:

other – MatchData to copy from, or None to clear.

MatchData.clear() → None#

Clear all match data and captured groups.

MatchData.starts(field: str) → list[int]#

Return the start indices of every capture of the specified field.

MatchData.spans(field: str) → list[Span]#

Return the spans of every capture of the specified field.

Examples

Locate every capture of a repeated group (see also starts() and ends()):

>>> import regex as re
>>> from my import MatchData
>>> data = MatchData(match=re.fullmatch(r'(?:(?P<word>\w+) ?)+', 'one two three'))
>>> data.spans('word')
[Span(0, 3), Span(4, 7), Span(8, 13)]
>>> data.starts('word')
[0, 4, 8]
>>> data.ends('word')
[3, 7, 13]
MatchData.ends(field: str) → list[int]#

Return the end indices of every capture of the specified field.

MatchData.matches(other: MatchData) → bool#

Determine if two MatchData objects have the same set of capture group names.

Parameters:

other – MatchData to compare against.

Returns:

True if both have the same keys (ignoring values and order).

Examples

Compare the captured shape, not the captured values:

>>> import regex as re
>>> from my import MatchData
>>> data = MatchData(match=re.fullmatch(r'(?:(?P<word>\w+) ?)+', 'one two three'))
>>> MatchData(data={'word': ['x']}).matches(data)
True