API reference#
Pattern#
- class remagic.Pattern(node=Seq(parts=()))[source]#
An immutable piece of regular expression.
Strings combined with a pattern are matched literally. Combining patterns adds (?:…) only where precedence requires it.
>>> (Pattern.literal("a") | "b").times(2).source '(?:a|b){2}'
- property source#
The regex source as built, before any optimisation.
- property precedence#
How tightly this pattern binds when combined.
- property needs_regex#
Whether only the regex module can compile this pattern.
- classmethod literal(text)[source]#
Match text exactly, escaping every special character.
- Return type:
- times(count, *, lazy=False, possessive=False)[source]#
Repeat exactly count times.
- Return type:
Example
>>> str(Pattern.literal("a").times(3)) 'a{3}'
- between(low, high, *, lazy=False, possessive=False)[source]#
Repeat from low to high times, inclusive.
- Return type:
Example
>>> str(Pattern.literal("a").between(2, 4)) 'a{2,4}'
- at_least(low, *, lazy=False, possessive=False)[source]#
Repeat low or more times.
- Return type:
Example
>>> str(Pattern.literal("a").at_least(2)) 'a{2,}'
- optional(*, lazy=False, possessive=False)[source]#
Match zero or one time.
- Return type:
Example
>>> str(Pattern.literal("a").optional(lazy=True)) 'a??'
- zero_or_more(*, lazy=False, possessive=False)[source]#
Match zero or more times.
- Return type:
Example
>>> str(Pattern.literal("ab").zero_or_more()) '(?:ab)*'
- one_or_more(*, lazy=False, possessive=False)[source]#
Match one or more times.
- Return type:
Example
>>> str(Pattern.literal("a").one_or_more(possessive=True)) 'a++'
- group(name=None)[source]#
Capture as a numbered group, or as a named group if name is given.
- Return type:
Example
>>> str(Pattern.literal("a").group("first")) '(?P<first>a)'
- non_capturing()[source]#
Group without capturing.
- Return type:
Example
>>> str(Pattern.literal("ab").non_capturing()) '(?:ab)'
- atomic()[source]#
Match without backtracking into the group.
- Return type:
Example
>>> str(Pattern.literal("a").atomic()) '(?>a)'
- scoped(on='', off='')[source]#
Apply inline flags to this pattern only.
on and off are flag letters as in (?i-s:…).
- Return type:
- ignore_case()[source]#
Match case-insensitively.
- Return type:
Example
>>> str(Pattern.literal("a").ignore_case()) '(?i:a)'
- followed_by(other)[source]#
Match this pattern only when other follows.
- Return type:
Example
>>> str(Pattern.literal("a").followed_by("b")) 'a(?=b)'
- not_followed_by(other)[source]#
Match this pattern only when other does not follow.
- Return type:
Example
>>> str(Pattern.literal("a").not_followed_by("b")) 'a(?!b)'
- preceded_by(other)[source]#
Match this pattern only when other precedes.
- Return type:
Example
>>> str(Pattern.literal("a").preceded_by("b")) '(?<=b)a'
- not_preceded_by(other)[source]#
Match this pattern only when other does not precede.
- Return type:
Example
>>> str(Pattern.literal("a").not_preceded_by("b")) '(?<!b)a'
- optimized(level='safe', flags=0)[source]#
Return the cheaper equivalent pattern that compile would use.
safe keeps match spans and groups identical. aggressive also factors and reorders alternatives, which can change which match is found, so use it with fullmatch or yes/no checks only.
- Return type:
Example
>>> import remagic as rm >>> str(rm.any_of("abc").one_or_more().one_or_more().optimized()) '[abc]++'
- compile(flags=0, *, engine='auto', optimize=True)[source]#
Compile with re, or with regex when the pattern needs it.
optimize rewrites the pattern to a cheaper one with the same matches (True or “safe”), also factors alternatives for fullmatch use (“aggressive”), or compiles the pattern as built (False).
- Raises:
RemagicException – if the chosen engine cannot compile the pattern.
- Return type:
Functions#
Free-function builders; each mirrors a Pattern method.
- remagic.interface.create(value)[source]#
Return value as a pattern; strings are matched literally.
- Return type:
- remagic.interface.optional(value, *, lazy=False, possessive=False)[source]#
Zero or one of value.
- Return type:
- remagic.interface.zero_or_more(value, *, lazy=False, possessive=False)[source]#
Zero or more of value.
- Return type:
- remagic.interface.one_or_more(value, *, lazy=False, possessive=False)[source]#
One or more of value.
- Return type:
- remagic.interface.times(value, count, *, lazy=False, possessive=False)[source]#
Exactly count of value.
- Return type:
- remagic.interface.between(value, low, high, *, lazy=False, possessive=False)[source]#
low to high of value.
- Return type:
- remagic.interface.at_least(value, low, *, lazy=False, possessive=False)[source]#
low or more of value.
- Return type:
- remagic.interface.group(value, name=None)[source]#
Capture value, optionally under name.
- Return type:
- remagic.interface.scoped(value, on='', off='')[source]#
Apply inline flags to value only.
- Return type:
- remagic.interface.any_of(values)[source]#
Match any one of values, trying them in order.
- Return type:
>>> str(any_of(["a.b", "c"])) 'a\\.b|c'
- remagic.interface.char_in(chars, *, ranges=())[source]#
Match one character from chars or from the inclusive ranges.
- Return type:
- remagic.interface.char_not_in(chars, *, ranges=())[source]#
Match one character that is not in chars or ranges.
- Return type:
- remagic.interface.char_range(low, high)[source]#
Match one character from low to high, inclusive.
- Return type:
- remagic.interface.unicode_property(name, *, negate=False)[source]#
Match a Unicode property such as L or Greek; needs regex.
- Return type:
- remagic.interface.before(value)[source]#
Assert that value follows the current position.
- Return type:
- remagic.interface.not_before(value)[source]#
Assert that value does not follow the current position.
- Return type:
- remagic.interface.after(value)[source]#
Assert that value precedes the current position.
- Return type:
Constants#
Ready-made patterns for common character classes and anchors.
- remagic.constants.CHAR = Pattern('.')#
Any character except a newline.
- remagic.constants.WHITESPACE = Pattern('\\s')#
One whitespace character; also available as WS.
- remagic.constants.WS = Pattern('\\s')#
One whitespace character; also available as WS.
- remagic.constants.NOT_WHITESPACE = Pattern('\\S')#
One non-whitespace character; also available as NOT_WS.
- remagic.constants.NOT_WS = Pattern('\\S')#
One non-whitespace character; also available as NOT_WS.
- remagic.constants.WORD = Pattern('\\w')#
One word character (letter, digit or underscore).
- remagic.constants.NOT_WORD = Pattern('\\W')#
One non-word character.
- remagic.constants.DIGIT = Pattern('\\d')#
One decimal digit.
- remagic.constants.NOT_DIGIT = Pattern('\\D')#
One character that is not a digit.
- remagic.constants.LETTER = Pattern('[A-Za-z]')#
One ASCII letter.
- remagic.constants.NOT_LETTER = Pattern('[^A-Za-z]')#
One character that is not an ASCII letter.
- remagic.constants.TAB = Pattern('\\t')#
A tab.
- remagic.constants.NEWLINE = Pattern('\\n')#
A newline; also available as N.
- remagic.constants.N = Pattern('\\n')#
A newline; also available as N.
- remagic.constants.NOT_NEWLINE = Pattern('[^\\n]')#
Any character except a newline; also available as NOT_N.
- remagic.constants.NOT_N = Pattern('[^\\n]')#
Any character except a newline; also available as NOT_N.
- remagic.constants.CARRIAGE_RETURN = Pattern('\\r')#
A carriage return; also available as R.
- remagic.constants.R = Pattern('\\r')#
A carriage return; also available as R.
- remagic.constants.START = Pattern('^')#
The start of the string, or of a line when multiline.
- remagic.constants.END = Pattern('$')#
The end of the string, or of a line when multiline.
- remagic.constants.START_OF_STRING = Pattern('\\A')#
The very start of the string.
- remagic.constants.END_OF_STRING = Pattern('\\Z')#
The very end of the string.
- remagic.constants.WORD_BOUNDARY = Pattern('\\b')#
The boundary between a word and a non-word character.
- remagic.constants.NOT_WORD_BOUNDARY = Pattern('\\B')#
Any position that is not a word boundary.
Exceptions#
Escape hatch#
Escape hatch for regex source that remagic cannot build.
Patterns made here are opaque: remagic cannot check or optimize them, and mistakes surface only when the engine compiles the result. Prefer the builders in remagic and reach for this module only when nothing there fits.