mirror of https://github.com/exaloop/codon.git
448 lines
17 KiB
Python
448 lines
17 KiB
Python
import re
|
|
import string
|
|
|
|
@test
|
|
def test_search_star_plus():
|
|
assert re.search('x*', 'axx').span(0) == (0, 0)
|
|
assert re.search('x*', 'axx').span() == (0, 0)
|
|
assert re.search('x+', 'axx').span(0) == (1, 3)
|
|
assert re.search('x+', 'axx').span() == (1, 3)
|
|
assert re.search('x', 'aaa') is None
|
|
assert re.match('a*', 'xxx').span(0) == (0, 0)
|
|
assert re.match('a*', 'xxx').span() == (0, 0)
|
|
assert re.match('x*', 'xxxa').span(0) == (0, 3)
|
|
assert re.match('x*', 'xxxa').span() == (0, 3)
|
|
assert re.match('a+', 'xxx') is None
|
|
test_search_star_plus()
|
|
|
|
@test
|
|
def test_branching():
|
|
"""Test Branching
|
|
Test expressions using the OR ('|') operator."""
|
|
assert re.match('(ab|ba)', 'ab').span() == (0, 2)
|
|
assert re.match('(ab|ba)', 'ba').span() == (0, 2)
|
|
assert re.match('(abc|bac|ca|cb)', 'abc').span() == (0, 3)
|
|
assert re.match('(abc|bac|ca|cb)', 'bac').span() == (0, 3)
|
|
assert re.match('(abc|bac|ca|cb)', 'ca').span() == (0, 2)
|
|
assert re.match('(abc|bac|ca|cb)', 'cb').span() == (0, 2)
|
|
assert re.match('((a)|(b)|(c))', 'a').span() == (0, 1)
|
|
assert re.match('((a)|(b)|(c))', 'b').span() == (0, 1)
|
|
assert re.match('((a)|(b)|(c))', 'c').span() == (0, 1)
|
|
test_branching()
|
|
|
|
@test
|
|
def test_basic_re_sub():
|
|
def bump_num(matchobj):
|
|
int_value = int(matchobj.group(0))
|
|
return str(int_value + 1)
|
|
|
|
assert re.sub('y', 'a', 'xyz') == 'xaz'
|
|
|
|
assert re.sub("(?i)b+", "x", "bbbb BBBB") == 'x x'
|
|
assert re.sub(r'\d+', bump_num, '08.2 -2 23x99y') == '9.3 -3 24x100y'
|
|
assert re.sub(r'\d+', bump_num, '08.2 -2 23x99y', 3) == '9.3 -3 23x99y'
|
|
assert re.sub(r'\d+', bump_num, '08.2 -2 23x99y', count=3) == '9.3 -3 23x99y'
|
|
|
|
assert re.sub('.', lambda m: r"\n", 'x') == '\\n'
|
|
assert re.sub('.', r"\n", 'x') == '\n'
|
|
|
|
s = r"\1\1"
|
|
assert re.sub('(.)', s, 'x') == 'xx'
|
|
assert re.sub('(.)', s.replace('\\', r'\\'), 'x') == s
|
|
assert re.sub('(.)', lambda m: s, 'x') == s
|
|
|
|
assert re.sub('(?P<a>x)', r'\g<a>\g<a>', 'xx') == 'xxxx'
|
|
assert re.sub('(?P<a>x)', r'\g<a>\g<1>', 'xx') == 'xxxx'
|
|
assert re.sub('(?P<unk>x)', r'\g<unk>\g<unk>', 'xx') == 'xxxx'
|
|
assert re.sub('(?P<unk>x)', r'\g<1>\g<1>', 'xx') == 'xxxx'
|
|
assert re.sub('()x', r'\g<0>\g<0>', 'xx') == 'xxxx'
|
|
|
|
assert re.sub('a', r'\t\n\v\r\f\a\b', 'a') == '\t\n\v\r\f\a\b'
|
|
assert re.sub('a', '\t\n\v\r\f\a\b', 'a') == '\t\n\v\r\f\a\b'
|
|
assert re.sub('a', '\t\n\v\r\f\a\b', 'a') == (chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7)+chr(8))
|
|
for c in 'cdehijklmopqsuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ':
|
|
try:
|
|
re.sub('a', '\\' + c, 'a')
|
|
assert False
|
|
except re.error:
|
|
pass
|
|
assert re.sub(r'^\s*', 'X', 'test') == 'Xtest'
|
|
test_basic_re_sub()
|
|
|
|
@test
|
|
def test_bug_449964():
|
|
assert re.sub(r'(?P<unk>x)', r'\g<1>\g<1>\b', 'xx') == 'xx\bxx\b'
|
|
test_bug_449964()
|
|
|
|
@test
|
|
def test_bug_449000():
|
|
# Test for sub() on escaped characters
|
|
assert re.sub(r'\r\n', r'\n', 'abc\r\ndef\r\n') == 'abc\ndef\n'
|
|
assert re.sub('\r\n', r'\n', 'abc\r\ndef\r\n') =='abc\ndef\n'
|
|
assert re.sub(r'\r\n', '\n', 'abc\r\ndef\r\n') == 'abc\ndef\n'
|
|
assert re.sub('\r\n', '\n', 'abc\r\ndef\r\n') == 'abc\ndef\n'
|
|
test_bug_449000()
|
|
|
|
@test
|
|
def test_sub_template_numeric_escape():
|
|
# bug 776311 and friends
|
|
assert re.sub('x', r'\0', 'x') == '\0'
|
|
assert re.sub('x', r'\000', 'x') == '\000'
|
|
assert re.sub('x', r'\001', 'x') == '\001'
|
|
assert re.sub('x', r'\008', 'x') == '\0' + '8'
|
|
assert re.sub('x', r'\009', 'x') == '\0' + '9'
|
|
assert re.sub('x', r'\111', 'x') == '\111'
|
|
assert re.sub('x', r'\117', 'x') == '\117'
|
|
assert re.sub('x', r'\377', 'x') == '\377'
|
|
|
|
assert re.sub('x', r'\1111', 'x'), '\1111'
|
|
assert re.sub('x', r'\1111', 'x'), '\111' + '1'
|
|
|
|
assert re.sub('x', r'\00', 'x') == '\x00'
|
|
assert re.sub('x', r'\07', 'x') == '\x07'
|
|
assert re.sub('x', r'\08', 'x') == '\0' + '8'
|
|
assert re.sub('x', r'\09', 'x') == '\0' + '9'
|
|
assert re.sub('x', r'\0a', 'x') == '\0' + 'a'
|
|
|
|
'''
|
|
self.checkTemplateError('x', r'\400', 'x',
|
|
r'octal escape value \400 outside of '
|
|
r'range 0-0o377', 0)
|
|
self.checkTemplateError('x', r'\777', 'x',
|
|
r'octal escape value \777 outside of '
|
|
r'range 0-0o377', 0)
|
|
|
|
self.checkTemplateError('x', r'\1', 'x', 'invalid group reference 1', 1)
|
|
self.checkTemplateError('x', r'\8', 'x', 'invalid group reference 8', 1)
|
|
self.checkTemplateError('x', r'\9', 'x', 'invalid group reference 9', 1)
|
|
self.checkTemplateError('x', r'\11', 'x', 'invalid group reference 11', 1)
|
|
self.checkTemplateError('x', r'\18', 'x', 'invalid group reference 18', 1)
|
|
self.checkTemplateError('x', r'\1a', 'x', 'invalid group reference 1', 1)
|
|
self.checkTemplateError('x', r'\90', 'x', 'invalid group reference 90', 1)
|
|
self.checkTemplateError('x', r'\99', 'x', 'invalid group reference 99', 1)
|
|
self.checkTemplateError('x', r'\118', 'x', 'invalid group reference 11', 1)
|
|
self.checkTemplateError('x', r'\11a', 'x', 'invalid group reference 11', 1)
|
|
self.checkTemplateError('x', r'\181', 'x', 'invalid group reference 18', 1)
|
|
self.checkTemplateError('x', r'\800', 'x', 'invalid group reference 80', 1)
|
|
self.checkTemplateError('x', r'\8', '', 'invalid group reference 8', 1)
|
|
'''
|
|
|
|
assert re.sub('(((((((((((x)))))))))))', r'\11', 'x') == 'x'
|
|
assert re.sub('((((((((((y))))))))))(.)', r'\118', 'xyz') == 'xz8'
|
|
assert re.sub('((((((((((y))))))))))(.)', r'\11a', 'xyz') == 'xza'
|
|
test_sub_template_numeric_escape()
|
|
|
|
@test
|
|
def test_qualified_re_sub():
|
|
assert re.sub('a', 'b', 'aaaaa') == 'bbbbb'
|
|
assert re.sub('a', 'b', 'aaaaa', 1) == 'baaaa'
|
|
assert re.sub('a', 'b', 'aaaaa', count=1) == 'baaaa'
|
|
test_qualified_re_sub()
|
|
|
|
@test
|
|
def test_bug_114660():
|
|
assert re.sub(r'(\S)\s+(\S)', r'\1 \2', 'hello there') == 'hello there'
|
|
test_bug_114660()
|
|
|
|
@test
|
|
def test_symbolic_refs():
|
|
assert re.sub('(?P<a>x)|(?P<b>y)', r'\g<b>', 'xx') == ''
|
|
assert re.sub('(?P<a>x)|(?P<b>y)', r'\2', 'xx') == ''
|
|
# Support > 100 groups.
|
|
pat = '|'.join(f'x(?P<a{i}>{hex(i)[2:]})y' for i in range(1, 200 + 1))
|
|
assert re.sub(pat, r'\g<200>', 'xc8yzxc8y') == 'c8zc8'
|
|
test_symbolic_refs()
|
|
|
|
@test
|
|
def test_re_subn():
|
|
assert re.subn("(?i)b+", "x", "bbbb BBBB") == ('x x', 2)
|
|
assert re.subn("b+", "x", "bbbb BBBB") == ('x BBBB', 1)
|
|
assert re.subn("b+", "x", "xyz") == ('xyz', 0)
|
|
assert re.subn("b*", "x", "xyz") == ('xxxyxzx', 4)
|
|
assert re.subn("b*", "x", "xyz", 2) == ('xxxyz', 2)
|
|
assert re.subn("b*", "x", "xyz", count=2) == ('xxxyz', 2)
|
|
test_re_subn()
|
|
|
|
# TODO: Current version does not allow None == None,
|
|
# so use this as a workaround.
|
|
def cmp_opt(x, y):
|
|
if x is None:
|
|
return y is None
|
|
elif y is None:
|
|
return x is None
|
|
else:
|
|
return unwrap(x) == unwrap(y)
|
|
|
|
def cmp_list(a, b):
|
|
if len(a) != len(b):
|
|
return False
|
|
|
|
for i in range(len(a)):
|
|
if not cmp_opt(a[i], b[i]):
|
|
return False
|
|
|
|
return True
|
|
|
|
def cmp_tuple(a, b):
|
|
if staticlen(a) != staticlen(b):
|
|
return False
|
|
elif staticlen(a) == 0:
|
|
return True
|
|
else:
|
|
if not cmp_opt(a[0], b[0]):
|
|
return False
|
|
return cmp_tuple(a[1:], b[1:])
|
|
|
|
@test
|
|
def test_re_split():
|
|
assert cmp_list(re.split(":", ":a:b::c"), ['', 'a', 'b', '', 'c'])
|
|
assert cmp_list(re.split(":+", ":a:b::c"), ['', 'a', 'b', 'c'])
|
|
assert cmp_list(re.split("(:+)", ":a:b::c"), ['', ':', 'a', ':', 'b', '::', 'c'])
|
|
|
|
assert cmp_list(re.split("(?::+)", ":a:b::c"), ['', 'a', 'b', 'c'])
|
|
assert cmp_list(re.split("(:)+", ":a:b::c"), ['', ':', 'a', ':', 'b', ':', 'c'])
|
|
assert cmp_list(re.split("([b:]+)", ":a:b::c"), ['', ':', 'a', ':b::', 'c'])
|
|
assert cmp_list(re.split("(b)|(:+)", ":a:b::c"), [None, '', None, ':', 'a', None, ':', '', 'b', None, '', None, '::', 'c'][1:])
|
|
assert cmp_list(re.split("(?:b)|(?::+)", ":a:b::c"), ['', 'a', '', '', 'c'])
|
|
|
|
for sep, expected in [
|
|
(':*', [None, '', '', 'a', '', 'b', '', 'c', ''][1:]),
|
|
('(?::*)', [None, '', '', 'a', '', 'b', '', 'c', ''][1:]),
|
|
('(:*)', [None, '', ':', '', '', 'a', ':', '', '', 'b', '::', '', '', 'c', '', ''][1:]),
|
|
('(:)*', [None, '', ':', '', None, 'a', ':', '', None, 'b', ':', '', None, 'c', None, ''][1:]),
|
|
]:
|
|
assert cmp_list(re.split(sep, ':a:b::c'), expected)
|
|
|
|
for sep, expected in [
|
|
('', ['', ':', 'a', ':', 'b', ':', ':', 'c', '']),
|
|
# (r'\b', [':', 'a', ':', 'b', '::', 'c', '']), # TODO: this fails; re2 difference maybe?
|
|
]:
|
|
assert cmp_list(re.split(sep, ':a:b::c'), expected)
|
|
test_re_split()
|
|
|
|
@test
|
|
def test_qualified_re_split():
|
|
assert cmp_list(re.split(":", ":a:b::c", 2), ['', 'a', 'b::c'])
|
|
assert cmp_list(re.split(":", ":a:b::c", maxsplit=2), ['', 'a', 'b::c'])
|
|
assert cmp_list(re.split(':', 'a:b:c:d', maxsplit=2), ['a', 'b', 'c:d'])
|
|
assert cmp_list(re.split("(:)", ":a:b::c", maxsplit=2), ['', ':', 'a', ':', 'b::c'])
|
|
assert cmp_list(re.split("(:+)", ":a:b::c", maxsplit=2), ['', ':', 'a', ':', 'b::c'])
|
|
assert cmp_list(re.split("(:*)", ":a:b::c", maxsplit=2), ['', ':', '', '', 'a:b::c'])
|
|
test_qualified_re_split()
|
|
|
|
@test
|
|
def test_re_findall():
|
|
assert re.findall(":+", "abc") == []
|
|
assert re.findall(":+", "a:b::c:::d") == [":", "::", ":::"]
|
|
assert re.findall("(:+)", "a:b::c:::d") == [":", "::", ":::"]
|
|
# (!) Note: this is different in Codon, as we always return the full match even
|
|
# if there are capturing groups.
|
|
assert re.findall("(:)(:*)", "a:b::c:::d") == [":", "::", ":::"]
|
|
|
|
x = "\xe0"
|
|
xx = x * 2
|
|
xxx = x * 3
|
|
string = f"a{x}b{xx}c{xxx}d"
|
|
assert re.findall(f"{x}+", string) == [x, xx, xxx]
|
|
assert re.findall(f"({x}+)", string) == [x, xx, xxx]
|
|
# (!) Note: same as above.
|
|
assert re.findall(f"({x})({x}*)", string) == [x, xx, xxx]
|
|
test_re_findall()
|
|
|
|
@test
|
|
def test_re_match():
|
|
assert cmp_list(re.match('a', 'a').groups(), List[Optional[str]]())
|
|
assert cmp_list(re.match('(a)', 'a').groups(), [None, 'a',][1:])
|
|
assert re.match('(a)', 'a').group(0).__val__() == 'a'
|
|
assert re.match('(a)', 'a').group(1).__val__() == 'a'
|
|
assert re.match('(a)', 'a').group(1, 1) == (Optional('a'), Optional('a'))
|
|
assert cmp_list(re.match('\xe0', '\xe0').groups(), List[Optional[str]]())
|
|
assert cmp_list(re.match('(\xe0)', '\xe0').groups(), ['\xe0'])
|
|
assert unwrap(re.match('(\xe0)', '\xe0').group(0)) == '\xe0'
|
|
assert unwrap(re.match('(\xe0)', '\xe0').group(1)) == '\xe0'
|
|
assert re.match('(\xe0)', '\xe0').group(1, 1) == (Optional('\xe0'), Optional('\xe0'))
|
|
|
|
pat = re.compile('((a)|(b))(c)?')
|
|
assert cmp_list(pat.match('a').groups(), [None, 'a', 'a', None, None][1:])
|
|
assert cmp_list(pat.match('b').groups(), [None, 'b', None, 'b', None][1:])
|
|
assert cmp_list(pat.match('ac').groups(), [None, 'a', 'a', None, 'c'][1:])
|
|
assert cmp_list(pat.match('bc').groups(), [None, 'b', None, 'b', 'c'][1:])
|
|
assert cmp_list(pat.match('bc').groups(""), [None, 'b', "", 'b', 'c'][1:])
|
|
|
|
pat = re.compile('(?:(?P<a1>a)|(?P<b2>b))(?P<c3>c)?')
|
|
assert cmp_tuple(pat.match('a').group(1, 2, 3), (Optional('a'), Optional[str](), Optional[str]()))
|
|
assert cmp_tuple(pat.match('b').group('a1', 'b2', 'c3'), (Optional[str](), Optional('b'), Optional[str]()))
|
|
assert cmp_tuple(pat.match('ac').group(1, 'b2', 3), (Optional('a'), Optional[str](), Optional('c')))
|
|
test_re_match()
|
|
|
|
def raises(exception: type, function, *args, **kwargs):
|
|
try:
|
|
function(*args, **kwargs)
|
|
except exception:
|
|
return True
|
|
except:
|
|
pass
|
|
return False
|
|
|
|
@test
|
|
def test_group():
|
|
class Index:
|
|
value: int
|
|
def __init__(self, value):
|
|
self.value = value
|
|
def __index__(self):
|
|
return self.value
|
|
# A single group
|
|
m = re.match('(a)(b)', 'ab')
|
|
assert m.group() == 'ab'
|
|
assert unwrap(m.group(0)) == 'ab'
|
|
assert unwrap(m.group(1)) == 'a'
|
|
assert unwrap(m.group(Index(1))) == 'a'
|
|
assert raises(IndexError, m.group, -1)
|
|
assert raises(IndexError, m.group, 3)
|
|
assert raises(IndexError, m.group, 1<<1000)
|
|
assert raises(IndexError, m.group, Index(1<<1000))
|
|
assert raises(IndexError, m.group, 'x')
|
|
# Multiple groups
|
|
assert cmp_tuple(m.group(2, 1), ('b', 'a'))
|
|
assert cmp_tuple(m.group(Index(2), Index(1)), ('b', 'a'))
|
|
test_group()
|
|
|
|
@test
|
|
def test_match_getitem():
|
|
pat = re.compile('(?:(?P<a1>a)|(?P<b2>b))(?P<c3>c)?')
|
|
|
|
m = pat.match('a')
|
|
assert unwrap(m['a1']) == 'a'
|
|
assert m['b2'] is None
|
|
assert m['c3'] is None
|
|
assert unwrap(m[0]) == 'a'
|
|
assert unwrap(m[1]) == 'a'
|
|
assert m[2] is None
|
|
assert m[3] is None
|
|
|
|
assert raises(IndexError, lambda i: m[i], 'X')
|
|
assert raises(IndexError, lambda i: m[i], -1)
|
|
assert raises(IndexError, lambda i: m[i], 4)
|
|
|
|
m = pat.match('ac')
|
|
assert unwrap(m['a1']) == 'a'
|
|
assert m['b2'] is None
|
|
assert unwrap(m['c3']) == 'c'
|
|
assert unwrap(m[0]) == 'ac'
|
|
assert unwrap(m[1]) == 'a'
|
|
assert m[2] is None
|
|
assert unwrap(m[3]) == 'c'
|
|
test_match_getitem()
|
|
|
|
@test
|
|
def test_re_fullmatch():
|
|
assert re.fullmatch(r"a", "a").span() == (0, 1)
|
|
assert re.fullmatch(r"a|ab", "ab").span() == (0, 2)
|
|
assert re.fullmatch("\xe0|\xe0\xdf", "\xe0\xdf").span() == (0, 2)
|
|
|
|
assert re.fullmatch(r".*?$", "abc").span() == (0, 3)
|
|
assert re.fullmatch(r".*?", "abc").span() == (0, 3)
|
|
assert re.fullmatch(r"a.*?b", "ab").span() == (0, 2)
|
|
assert re.fullmatch(r"a.*?b", "abb").span() == (0, 3)
|
|
assert re.fullmatch(r"a.*?b", "axxb").span() == (0, 4)
|
|
assert re.fullmatch(r"a+", "ab") is None
|
|
assert re.fullmatch(r"abc$", "abc\n") is None
|
|
assert re.fullmatch(r"(?m)abc$", "abc\n") is None
|
|
|
|
assert re.compile(r"bc").fullmatch("abcd", pos=1, endpos=3).span() == (1, 3)
|
|
# TODO: following fails; $ does not respect endpos in re2?
|
|
#assert re.compile(r".*?$").fullmatch("abcd", pos=1, endpos=3).span() == (1, 3)
|
|
assert re.compile(r".*?").fullmatch("abcd", pos=1, endpos=3).span() == (1, 3)
|
|
test_re_fullmatch()
|
|
|
|
@test
|
|
def test_finditer():
|
|
iter = re.finditer(r":+", "a:b::c:::d")
|
|
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
|
|
|
|
pat = re.compile(r":+")
|
|
iter = pat.finditer("a:b::c:::d", 1, 10)
|
|
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
|
|
|
|
pat = re.compile(r":+")
|
|
iter = pat.finditer("a:b::c:::d", pos=1, endpos=10)
|
|
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
|
|
|
|
pat = re.compile(r":+")
|
|
iter = pat.finditer("a:b::c:::d", endpos=10, pos=1)
|
|
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
|
|
|
|
pat = re.compile(r":+")
|
|
iter = pat.finditer("a:b::c:::d", pos=3, endpos=8)
|
|
assert cmp_list([item.group(0) for item in iter], ["::", "::"])
|
|
test_finditer()
|
|
|
|
@test
|
|
def test_constants():
|
|
assert re.I == re.IGNORECASE
|
|
assert re.L == re.LOCALE
|
|
assert re.M == re.MULTILINE
|
|
assert re.S == re.DOTALL
|
|
assert re.X == re.VERBOSE
|
|
test_constants()
|
|
|
|
@test
|
|
def test_anyall():
|
|
assert unwrap(re.match("a.b", "a\nb", re.DOTALL).group(0)) == "a\nb"
|
|
assert unwrap(re.match("a.*b", "a\n\nb", re.DOTALL).group(0)) == "a\n\nb"
|
|
test_anyall()
|
|
|
|
@test
|
|
def test_groupdict():
|
|
d = re.match('(?P<first>first) (?P<second>second)', 'first second').groupdict()
|
|
assert len(d) == 2 and unwrap(d['first']) == 'first' and unwrap(d['second']) == 'second'
|
|
test_groupdict()
|
|
|
|
@test
|
|
def test_expand():
|
|
assert re.match("(?P<first>first) (?P<second>second)", "first second").expand(r"\2 \1 \g<second> \g<first>") == "second first second first"
|
|
assert re.match("(?P<first>first)|(?P<second>second)", "first").expand(r"\2 \g<second>") == " "
|
|
test_expand()
|
|
|
|
@test
|
|
def test_getattr():
|
|
assert re.compile("(?i)(a)(b)").pattern == "(?i)(a)(b)"
|
|
# TODO: Codon does not support flags like this
|
|
# self.assertEqual(re.compile("(?i)(a)(b)").flags, re.I | re.U)
|
|
assert re.compile("(?i)(a)(b)").groups == 2
|
|
assert re.compile("(?i)(a)(b)").groupindex == {}
|
|
assert re.compile("(?i)(?P<first>a)(?P<other>b)").groupindex == {'first': 1, 'other': 2}
|
|
|
|
assert re.match("(a)", "a").pos == 0
|
|
assert re.match("(a)", "a").endpos == 1
|
|
assert re.match("(a)", "a").string == "a"
|
|
assert re.match("(a)", "a").re
|
|
test_getattr()
|
|
|
|
def check_match(pattern, text, match: Optional[str] = None, span: Optional[re.Span] = None, matcher = re.fullmatch):
|
|
if match is None and span is None:
|
|
# the pattern matches the whole text
|
|
match = text
|
|
span = (0, len(text))
|
|
elif match is None or span is None:
|
|
raise ValueError('If match is not None, span should be specified '
|
|
'(and vice versa).')
|
|
m = matcher(pattern, text)
|
|
return bool(m) and m.group() == match and m.span() == span
|
|
|
|
LITERAL_CHARS = string.ascii_letters + string.digits
|
|
|
|
@test
|
|
def test_re_escape():
|
|
p = ''.join(chr(i) for i in range(256))
|
|
for c in p:
|
|
assert check_match(re.escape(c), c)
|
|
assert check_match('[' + re.escape(c) + ']', c)
|
|
assert check_match(re.escape(p), p)
|
|
for c in '-.]{}':
|
|
assert re.escape(c)[:1] == '\\'
|
|
literal_chars = LITERAL_CHARS
|
|
assert re.escape(literal_chars) == literal_chars
|
|
test_re_escape()
|