# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['rgx']

package_data = \
{'': ['*']}

setup_kwargs = {
    'name': 'rgx',
    'version': '1.1.1',
    'description': 'Typed, simple and readable regexp generation',
    'long_description': 'Many people complain about unreadable and complex syntax of regular expressions.    \nMany others complain about how they can\'t remember all constructs and features.\n\n`rgx` solves those problems: it is a straightforward regexp builder. It also places parens where needed to respect intended operator priority.    \nIt can produce a regular expression string to use in `re.compile` or any other regex library of your choice.    \n\nIn other words, with `rgx` you can build a regular expression from parts, using straightforward and simple expressions.\n\n## Installation\n\n`pip install rgx`\n\nThat\'s it.\n\n## Basic usage\n\n### Hello, regex world\n\n```python\nimport rgx\nimport re\n\nword = rgx.meta.WORD_CHAR.many().capture() # (\\w+), a capturing group\ncomma = rgx.pattern(",").maybe()\n\nregex = rgx.pattern((\n    "hello",\n    comma,\n    rgx.meta.WHITESPACE,\n    (\n        word + rgx.meta.WHITESPACE\n    ).maybe(),\n    "world"\n)) # (?:hello,?\\s(?:(\\w+)\\s)?world)\n\nre.compile(\n    regex.render_str("i") # global flag (case-insensitive)\n)\n\n```\n\n### Match some integers\n\nthis regex will match valid Python integer literals:\n\n```python\nimport rgx\nimport re\n\nnonzero = rgx.char_range("1", "9") # [1-9]\nzero = "0"\ndigit = zero | nonzero # 0|[1-9]\ninteger = zero | (nonzero + digit.some()) # 0|[1-9](?:0|[1-9])*\n\nint_regex = re.compile(str(integer))\n\n```\n\n...or this one:\n\n```python\nimport rgx\nimport re\n\nnonzero = rgx.char_range("1", "9") # [1-9]\ndigit = rgx.meta.DIGIT # \\d\ninteger = digit | (nonzero + digit.some()) # \\d|[1-9]\\d*\n\nint_regex = re.compile(str(integer))\n\n```\n\n## Quickstart\n\n*in this readme, `x` means some pattern object. Occasionaly, `y` is introduced to mean some other pattern object (or literal)*\n\n### Literals and pattern objects\n\n`rgx` operates mostly on so-called "pattern objects" — `rgx.entities.RegexPattern` istances.    \nYour starting point would be `rgx.pattern` — it creates pattern objects from literals (and from pattern objects, which doesn\'t make a lot of sense).\n\n- `rgx.pattern(str, escape: bool = True)` creates a literal pattern — one that exactly matches given string. If you want to disable escaping, pass `escape=False`\n- `rgx.pattern(tuple[AnyRegexPattern])` creates a non-capturing group of patterns (nested literals will be converted too)\n- `rgx.pattern(list[str])` creates a character class (for example, `rgx.pattern(["a", "b", "c"])` creates pattern `[abc]`, that matches any character of those in brackets)\n\nMost operations with pattern objects support using Python literals on one side, for example: `rgx.pattern("a") | b` would produce `a|b` pattern object (specifically, `rgx.entities.Option`)    \n\n### Rendering patterns\n\n```python\n\nimport rgx\n\nx = rgx.pattern("x")\npattern = x | x\n\nrendered_with_str = str(pattern) # "x|x"\nrendered_with_method = pattern.render_str() # "x|x"\nrendered_with_method_flags = pattern.render_str("im") # (?im)x|x\n```    \n\n### Capturing Groups\n\n```python\nimport rgx\n\nx = rgx.pattern("x")\n\nprint(x.capture()) # (x)\n\nprint(rgx.reference(1)) # \\1\n\n\nnamed_x = x.named("some_x") # x.named(name: str)\n\nprint(named_x) # (?P<some_x>x)\n\nnamed_x_reference = rgx.named("some_x")\n\nprint(named_x_reference) # (?P=x)\n\n```\n\nTo create a capturing group, use `x.capture()`, or `rgx.reference(group: int)` for a reference.    \nTo create a named capturing group, use `rgx.named(name: str, x)`, or `rgx.named(name: str)` for a named reference.    \n\n### Character classes\n\n```python\nimport rgx\n\n\naz = rgx.char_range("a", "z") # rgx.char_range(start?: str, stop?: str)\nprint(az) # [a-z]\n\ndigits_or_space = rgx.pattern(["1", "2", "3", rgx.meta.WHITESPACE]) \nprint(digits_or_space) # [123\\s]\n\nprint(az | digits_or_space) # [a-z123\\s]\n\n# [^a-z123\\s]\nprint(\n    (az | digits_or_space).reverse() # rgx.entities.Chars.reverse(self)\n)\n\n```  \n\n### Conditional pattern\n\n```python\nimport rgx\n\nx = rgx.pattern("x")\ny = rgx.pattern("y")\nz = rgx.pattern("z")\n\ncapture = x.capture()\n\n# (x)(?(1)y|z)\nprint(\n    capture + rgx.conditional(1, y, z)\n)\n``` \n\n## Docs\n\n### Pattern methods\n\n#### `pattern.render_str(flags: str = \'\') -> str`\n\nRenders given pattern into a string with specified global flags.\n\n---\n\n#### `pattern.set_flags(flags: str) -> LocalFlags`\n\nThis method adds local flags to given pattern\n\n```python\nx.flags("y") # "(?y:x)"\n```\n\n---\n\n#### `pattern.concat(other: AnyRegexPattern) -> Concat`\n\nUse to match one pattern and then another.\n\n`A.concat(B)` is equivalent to `A + B` (works if either A or B is a RegexPart object, not a Python literal)\n\n```python\nx.concat(y) # "xy"\nx + y # "xy"\n```\n\n---\n\n#### `pattern.option(other: AnyRegexPattern) -> Option`\n\nUse to match either one pattern or another.\n\n`A.option(B)` is equivalent to `A | B` (if either A or B is a RegexPart object, not a Python literal)\n\n```python\nx.option(y) # "x|y"\nx | y # "x|y"\n```\n\n---\n\n#### `pattern.many(lazy: bool = False) -> Many`\n\nUse this for repeating patterns (one or more times)\n\nWhen not lazy, matches as many times as possible, otherwise matches as few times as possible.\n\n```python\nx.many() # "x+"\nx.many(True) # "x+?"\n```\n\n---\n\n#### `pattern.some(lazy: bool = False) -> Some`\n\nUse this for repeating optional patterns (zero or more times)\n\nWhen not lazy, matches as many times as possible, otherwise matches as few times as possible.\n\n```python\nx.some() # "x*"\nx.some(True) # "x*?"\n```\n\n---\n\n#### `pattern.maybe(lazy: bool = False) -> Maybe`\n\nUse this for optional patterns (zero or one times)\n\nWhen not lazy, matches as many times as possible, otherwise matches as few times as possible.\n\n```python\nx.maybe() # "x?"\nx.maybe(True) # "x??"\n```\n\n---\n\n#### `pattern.x_or_less_times(count: int, lazy: bool = False) -> Range`\n\nUse this to match pattern x or less times (hence the name).\n\nWhen not lazy, matches as many times as possible, otherwise matches as few times as possible.\n\n```python\nx.x_or_less_times(5) # "x{,5}"\nx.x_or_less_times(5, True) # "x{,5}?"\n```\n\n---\n\n#### `pattern.x_or_more_times(count: int, lazy: bool = False) -> Range`\n\nUse this to match pattern x or more times (hence the name).\n\nWhen not lazy, matches as many times as possible, otherwise matches as few times as possible.\n\n```python\nx.x_or_more_times(5) # "x{5,}"\nx.x_or_more_times(5, True) # "x{5,}?"\n```\n\n---\n\n#### `pattern.x_times(count: int, lazy: bool = False) -> Range`\n\nUse this to match pattern exactly x times (hence the name).\n\nWhen not lazy, matches as many times as possible, otherwise matches as few times as possible.\n\n```python\nx.x_times(5) # "x{5}"\nx.x_times(5, True) # "x{5}?"\n```\n\n---\n\n#### `pattern.between_x_y_times(min_count: int, max_count: int, lazy: bool = False) -> Range`\n\nUse this to match pattern between x and y times, inclusive (hence the name).\n\nWhen not lazy, matches as many times as possible, otherwise matches as few times as possible.\n\n```python\nx.between_x_y_times(5, 6) # "x{5,6}"\nx.between_x_y_times(5, 6, True) # "x{5,6}?"\n```\n\n---\n\n#### `pattern.lookahead(other: RegexPattern) -> Concat`\n\nUse this to indicate that given pattern occurs before some another pattern (lookahead).\n\nIn other words, `x.lookahead(y)` matches a pattern `x` only if there is `y` after it\n\nLookahead pattern won\'t be captured.\n\n```python\nx.lookahead(y) # x(?=y)\nx.before(y) # x(?=y)\n```\n\n---\n\n#### `pattern.negative_lookahead(other) -> Concat`\n\nUse this to indicate that given pattern doesn\'t occur before some another pattern (negative lookahead).\n\nIn other words, `x.negative_lookahead(y)` matches a pattern `x` only if there is no `y` after it\n\nLookahead pattern won\'t be captured.\n\n```python\nx.negative_lookahead(y) # x(?!y)\nx.not_before(y) # x(?!y)\n```\n\n---\n\n#### `pattern.lookbehind(other: RegexPattern) -> Concat`\n\nUse this to indicate that given pattern occurs after some another pattern (lookbehind).\n\nIn other words, `x.lookbehind(y)` matches a pattern `x` only if there is `y` before it\n\nLookbehind pattern won\'t be captured.\n\n```python\nx.lookbehind(y) # (?<=y)x\nx.after(y) # (?<=y)x\n```\n\n---\n\n#### `pattern.negative_lookbehind(other) -> Concat`\n\nUse this to indicate that given pattern goes before some another pattern (negative lookbehind).\n\nIn other words, `x.negative_lookbehind(y)` matches a pattern `x` only if there is NO `y` before it\n\nLookbehind pattern won\'t be captured.\n\n```python\nx.negative_lookbehind(y) # (?<!y)x\nx.not_after(y) # (?<!y)x\n```\n\n---\n\n#### `pattern.capture() -> Group`\n\nUse this to make a capturing group out of pattern.\n\n```python\nx.capture() # (x)\n```\n\n### Meta\n\n`rgx.meta` is a collection of different meta-sequences and anchors:\n\n```python\nWORD_CHAR = UnescapedLiteral(r"\\w")\nNON_WORD_CHAR = UnescapedLiteral(r"\\W")\nDIGIT = UnescapedLiteral(r"\\d")\nNON_DIGIT = UnescapedLiteral(r"\\D")\nWHITESPACE = UnescapedLiteral(r"\\s")\nNON_WHITESPACE = UnescapedLiteral(r"\\S")\nWORD_BOUNDARY = UnescapedLiteral(r"\\b")\nNON_WORD_BOUNDARY = UnescapedLiteral(r"\\B")\nANY = UnescapedLiteral(".")\nNEWLINE = UnescapedLiteral(r"\\n")\nCARRIAGE_RETURN = UnescapedLiteral(r"\\r")\nTAB = UnescapedLiteral(r"\\t")\nNULL_CHAR = UnescapedLiteral(r"\\0")\nSTRING_START = UnescapedLiteral("^")\nSTRING_END = UnescapedLiteral("$")\n```\n\n## Common questions\n\n### Difference between `(x, y)` and `x + y`\n\nPrevious examples used `()` and `+`, and the difference might not be so obvious.    \n\n- `x + y` creates a concatenation of patterns (`rgx.entities.Concat`), with no extra characters apart from those of patterns\n- `x + y` can be used only if at least one of the operands is a pattern object (that is, created with one of `rgx` functions or is one of `rgx` constants)\n- `x + y` produces a pattern object itself, so you won\'t need to call `pattern` on it to call pattern methods\n\n- `pattern((x, y))` creates a non-capturing group (`rgx.entities.NonCapturingGroup`): `pattern((x, y)).render_str()` -> `(?:xy)`\n- `(x, y)` can be used with any pattern-like literals or pattern objects\n- `(x, y)` is a tuple literal, so you can\'t use pattern methods on it directly or convert it into a complete expression (you need to use `rgx.pattern` on it first)',
    'author': 'Dmitry Gritsenko',
    'author_email': 'k01419q45@ya.ru',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/courage-tci/gekkota',
    'packages': packages,
    'package_data': package_data,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
