regex-compose


Nameregex-compose JSON
Version 0.0.3 PyPI version JSON
download
home_pageNone
SummaryCompose multiple regular expressions into one using a special syntax
upload_time2024-04-05 19:14:17
maintainerNone
docs_urlNone
authorShae.c32
requires_python>=3.9
licenseNone
keywords re regex regular expression
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # What it is
A regular expression builder that manages cross-pattern references
and allows for easy runtime mutability by default

## Features

### Simple syntax
The syntax for cross-referencing regular expressions is simple, and defined by a small
(customizable) regular expression, which by default matches text like `(?~name)`

### Automatic reference management
When using a `PatternComposer`, patterns are automatically tracked, so that when one
changes, all the patterns that depend on it are recompiled as well

# Why & priorities
When working on my programming language, [Caustic](https://codeberg.org/Caustic),
I was displeased at most of the parsers I found, and decided to make my own. For
the parsing of regular expressions, I needed support for **runtime modification** due
to Caustic's variable syntax. As such, arbitrary modifications can be made to the
patterns by modifying either the pattern itself, or patterns it depends on.

# Expression syntax
Sub parts are denoted like `(?~name)` by default, but can be changed to any regular expression.
As such, the following syntax and examples are only valid with the default part-pattern.

|   Name   |         Pattern         |
| :------: | :---------------------- |
| `part_a` |          `\d`           |
| `part_b` |       `[a-zA-Z]`        |
|  `patt`  | `(?~part_a):(?~part_b)` |

Given the table of patterns above, the pattern `patt` compiles to:
> `\d:[a-zA-Z]`

If `part_a` was changed to `-?\d`, then `patt` would recompile to:
> `-?\d:[a-zA-Z]`

# Examples
Note that examples are given with the default matching pattern, so references will be made as `(?~name)`

## [/examples/pragma-parser-2.py](https://codeberg.org/Shae/RegExCompose/src/branch/main/examples/pragma-parser-2.py)
The following script runs a REPL that will match each line of input against
a "pragma" statement that can change the patterns on-the-fly

```python3
#> Imports
import re
import regex_compose
#</Imports

#> Header
base_patterns = {
    'word': r'\w',
    'number': r'\d',
    'wordnum': r'(?~word)|(?~number)',
}

pragma_patterns = {
    'pragma.start': r'^\$',
    'pragma.stop': r'$',
    'pragma.key': r'(?P<key>(?:(?~wordnum)|\.)+)',
    'pragma.delim': r':',
    'pragma.val': r'(?P<val>.*?)',
    'pragma.flags': r'(?m)',
    'pragma': r'(?~pragma.flags)(?~pragma.start)(?~pragma.key)(?~pragma.delim)(?~pragma.val)(?~pragma.stop)',
}
#</Header

#> Main >/
# Create parser and add `base_patterns` and `pragma_patterns`
p = regex_compose.PatternComposer()
p.multiadd(base_patterns)
p.multiadd(pragma_patterns)

print(f'Pragma pattern: {rc.patterns["pragma"]}\n -> {rc.compiled["pragma"]}')
while True:
    inp = input('Enter text to parse > ')
    if m := re.match(p['pragma'], inp):
        rc.add(m.group('key'), m.group('val'), replace=True)
        print(p.compiled['pragma'])
    else: print(inp) # echo the line back when there's no pragma
```

| Input              | Output
| :----------------- | :-----
|  N/A               | `Pragma pattern: (?~pragma.flags)(?~pragma.start)(?~pragma.key)(?~pragma.delim)(?~pragma.val)(?~pragma.stop)`
|  N/A               | ` -> (?m)^\$(?P<key>(?:\w\|\d\|\.)+):(?P<val>.*?)$`
| `test`             | `test`
| `$pragma.start:%`  | `(?m)%(?P<key>(?:\w\|\d\|\.)+):(?P<val>.*?)$`
| `%pragma.stop:;`   | `(?m)%(?P<key>(?:\w\|\d\|\.)+):(?P<val>.*?);`
| `%pragma.delim:=;` | `(?m)%(?P<key>(?:\w\|\d\|\.)+)=(?P<val>.*?);`

## Further examples
For further examples, see [https://codeberg.org/Shae/RegExCompose/src/branch/main/examples](https://codeberg.org/Shae/RegExCompose/src/branch/main/examples)

# Changelog

## v0.0.3
- Fixed an issue in `PatternComposer.multiadd()` due to incorrect name access
- Fixed `refpatt_patt` not being passed to `get_refpatt_parts` in `PatternComposer.multiadd()`, causing an error when in `bytes_mode`

## v0.0.2
- Added support for bytes

# Links
- Source code: [https://codeberg.org/Shae/RegExCompose](https://codeberg.org/Shae/RegExCompose)
- License: [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "regex-compose",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "re, regex, regular, expression",
    "author": "Shae.c32",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/ef/59/8e4b570255295e36a1d7ad63be9c8e4eb27b5943b79033fab5028bab2650/regex-compose-0.0.3.tar.gz",
    "platform": null,
    "description": "# What it is\nA regular expression builder that manages cross-pattern references\nand allows for easy runtime mutability by default\n\n## Features\n\n### Simple syntax\nThe syntax for cross-referencing regular expressions is simple, and defined by a small\n(customizable) regular expression, which by default matches text like `(?~name)`\n\n### Automatic reference management\nWhen using a `PatternComposer`, patterns are automatically tracked, so that when one\nchanges, all the patterns that depend on it are recompiled as well\n\n# Why & priorities\nWhen working on my programming language, [Caustic](https://codeberg.org/Caustic),\nI was displeased at most of the parsers I found, and decided to make my own. For\nthe parsing of regular expressions, I needed support for **runtime modification** due\nto Caustic's variable syntax. As such, arbitrary modifications can be made to the\npatterns by modifying either the pattern itself, or patterns it depends on.\n\n# Expression syntax\nSub parts are denoted like `(?~name)` by default, but can be changed to any regular expression.\nAs such, the following syntax and examples are only valid with the default part-pattern.\n\n|   Name   |         Pattern         |\n| :------: | :---------------------- |\n| `part_a` |          `\\d`           |\n| `part_b` |       `[a-zA-Z]`        |\n|  `patt`  | `(?~part_a):(?~part_b)` |\n\nGiven the table of patterns above, the pattern `patt` compiles to:\n> `\\d:[a-zA-Z]`\n\nIf `part_a` was changed to `-?\\d`, then `patt` would recompile to:\n> `-?\\d:[a-zA-Z]`\n\n# Examples\nNote that examples are given with the default matching pattern, so references will be made as `(?~name)`\n\n## [/examples/pragma-parser-2.py](https://codeberg.org/Shae/RegExCompose/src/branch/main/examples/pragma-parser-2.py)\nThe following script runs a REPL that will match each line of input against\na \"pragma\" statement that can change the patterns on-the-fly\n\n```python3\n#> Imports\nimport re\nimport regex_compose\n#</Imports\n\n#> Header\nbase_patterns = {\n    'word': r'\\w',\n    'number': r'\\d',\n    'wordnum': r'(?~word)|(?~number)',\n}\n\npragma_patterns = {\n    'pragma.start': r'^\\$',\n    'pragma.stop': r'$',\n    'pragma.key': r'(?P<key>(?:(?~wordnum)|\\.)+)',\n    'pragma.delim': r':',\n    'pragma.val': r'(?P<val>.*?)',\n    'pragma.flags': r'(?m)',\n    'pragma': r'(?~pragma.flags)(?~pragma.start)(?~pragma.key)(?~pragma.delim)(?~pragma.val)(?~pragma.stop)',\n}\n#</Header\n\n#> Main >/\n# Create parser and add `base_patterns` and `pragma_patterns`\np = regex_compose.PatternComposer()\np.multiadd(base_patterns)\np.multiadd(pragma_patterns)\n\nprint(f'Pragma pattern: {rc.patterns[\"pragma\"]}\\n -> {rc.compiled[\"pragma\"]}')\nwhile True:\n    inp = input('Enter text to parse > ')\n    if m := re.match(p['pragma'], inp):\n        rc.add(m.group('key'), m.group('val'), replace=True)\n        print(p.compiled['pragma'])\n    else: print(inp) # echo the line back when there's no pragma\n```\n\n| Input              | Output\n| :----------------- | :-----\n|  N/A               | `Pragma pattern: (?~pragma.flags)(?~pragma.start)(?~pragma.key)(?~pragma.delim)(?~pragma.val)(?~pragma.stop)`\n|  N/A               | ` -> (?m)^\\$(?P<key>(?:\\w\\|\\d\\|\\.)+):(?P<val>.*?)$`\n| `test`             | `test`\n| `$pragma.start:%`  | `(?m)%(?P<key>(?:\\w\\|\\d\\|\\.)+):(?P<val>.*?)$`\n| `%pragma.stop:;`   | `(?m)%(?P<key>(?:\\w\\|\\d\\|\\.)+):(?P<val>.*?);`\n| `%pragma.delim:=;` | `(?m)%(?P<key>(?:\\w\\|\\d\\|\\.)+)=(?P<val>.*?);`\n\n## Further examples\nFor further examples, see [https://codeberg.org/Shae/RegExCompose/src/branch/main/examples](https://codeberg.org/Shae/RegExCompose/src/branch/main/examples)\n\n# Changelog\n\n## v0.0.3\n- Fixed an issue in `PatternComposer.multiadd()` due to incorrect name access\n- Fixed `refpatt_patt` not being passed to `get_refpatt_parts` in `PatternComposer.multiadd()`, causing an error when in `bytes_mode`\n\n## v0.0.2\n- Added support for bytes\n\n# Links\n- Source code: [https://codeberg.org/Shae/RegExCompose](https://codeberg.org/Shae/RegExCompose)\n- License: [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Compose multiple regular expressions into one using a special syntax",
    "version": "0.0.3",
    "project_urls": {
        "Homepage": "https://codeberg.org/Shae/RegExCompose",
        "Issues": "https://codeberg.org/Shae/RegExCompose/issues"
    },
    "split_keywords": [
        "re",
        " regex",
        " regular",
        " expression"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "973863d029357f12423ac9051210f458056937b6ab718832ae8949dda3c60052",
                "md5": "642c27ce615f5b2d0cd69764df126f78",
                "sha256": "41db2ba33dcdf5a83e135ba0f9e4dcfb32af6c309d3f44048b4995d6d5b3b1d0"
            },
            "downloads": -1,
            "filename": "regex_compose-0.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "642c27ce615f5b2d0cd69764df126f78",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 6859,
            "upload_time": "2024-04-05T19:14:15",
            "upload_time_iso_8601": "2024-04-05T19:14:15.320405Z",
            "url": "https://files.pythonhosted.org/packages/97/38/63d029357f12423ac9051210f458056937b6ab718832ae8949dda3c60052/regex_compose-0.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ef598e4b570255295e36a1d7ad63be9c8e4eb27b5943b79033fab5028bab2650",
                "md5": "9af8c30533c62181275171156d22fdca",
                "sha256": "f2927831d13ca3dd522afbaac4eb08a9686403f478efc435e8c34672f795d09c"
            },
            "downloads": -1,
            "filename": "regex-compose-0.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "9af8c30533c62181275171156d22fdca",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 6551,
            "upload_time": "2024-04-05T19:14:17",
            "upload_time_iso_8601": "2024-04-05T19:14:17.175486Z",
            "url": "https://files.pythonhosted.org/packages/ef/59/8e4b570255295e36a1d7ad63be9c8e4eb27b5943b79033fab5028bab2650/regex-compose-0.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-05 19:14:17",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": true,
    "codeberg_user": "Shae",
    "codeberg_project": "RegExCompose",
    "lcname": "regex-compose"
}
        
Elapsed time: 0.26640s