Bidirectional Patterns

BidirectionalPattern enables round-trip parsing: parse a string, modify the extracted values, and format them back while maintaining the original format constraints.

Basic Usage

Create a BidirectionalPattern and parse a string:

>>> from formatparse import BidirectionalPattern
>>> formatter = BidirectionalPattern("{name:>10}: {value:05d}")
>>> result = formatter.parse("      John: 00042")
>>> result.named['name']
'John'
>>> result.named['value']
42

Formatting Back

The BidirectionalResult object can format itself back using the original pattern:

>>> result.format()
'      John: 00042'

Modifying Values

You can modify the extracted values and format them back:

>>> result.named['value'] = 100
>>> result.format()
'      John: 00100'

>>> result.named['name'] = "Alice"
>>> result.format()
'     Alice: 00100'

Validation

Validate values against the pattern’s constraints:

>>> result.named['value'] = 42
>>> is_valid, errors = result.validate()
>>> is_valid
True
>>> errors
[]

>>> result.named['value'] = "not a number"
>>> is_valid, errors = result.validate()
>>> is_valid
False
>>> len(errors) > 0
True

Using format() Method Directly

You can also use the pattern’s format() method directly:

>>> formatted = formatter.format({"name": "Alice", "value": 42})
>>> formatted.startswith("     Alice")
True
>>> "00042" in formatted
True

Real-World Use Cases

Configuration File Updates

Parse configuration files, modify values, and write them back:

formatter = BidirectionalPattern("PORT={port:05d}")
result = formatter.parse("PORT=00080")
result.named['port'] = 8080
new_config = result.format()
print(new_config)
PORT=08080

Data Transformation Pipelines

Transform data while maintaining format constraints:

>>> formatter = BidirectionalPattern("ID:{id:05d} Name:{name:>10}")
>>> result = formatter.parse("ID:00042 Name:      John")
>>> result.named['id']
42
>>> result.named['id'] = 100
>>> result.named['name'] = "Alice"
>>> formatted = result.format()
>>> formatted.startswith("ID:00100 Name:")
True
>>> formatted.endswith("Alice")
True

Form Validation

Validate user input against expected formats:

formatter = BidirectionalPattern("{username:>10}: {score:05d}")
user_input = "     alice: 00100"
result = formatter.parse(user_input)

if result:
    is_valid, errors = result.validate()
    if is_valid:
        print(f"Valid input: {result.format()}")
    else:
        print(f"Validation errors: {errors}")
else:
    print("Input does not match pattern")
Valid input:      alice: 00100