import sre_compile
import sre_parse
-__all__ = ["match","search","sub","subn","split","findall","compile",
- "purge","template","escape","I","L","M","S","X","U","IGNORECASE",
- "LOCALE","MULTILINE","DOTALL","VERBOSE","UNICODE","error"]
+# public symbols
+__all__ = [ "match", "search", "sub", "subn", "split", "findall",
+ "compile", "purge", "template", "escape", "I", "L", "M", "S", "X",
+ "U", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE",
+ "UNICODE", "error" ]
+
+# this module works under 1.5.2 and later. don't use string methods
+import string
# flags
I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case
def template(pattern, flags=0):
"Compile a template pattern, returning a pattern object"
-
return _compile(pattern, flags|T)
def escape(pattern):
def _join(seq, sep):
# internal: join into string having the same type as sep
- return sep[:0].join(seq)
+ return string.join(seq, sep[:0])
def _compile(*key):
# internal: compile pattern
# XXX: show string offset and offending character for all errors
-import sys
+# this module works under 1.5.2 and later. don't use string methods
+import string, sys
from sre_constants import *
-__all__ = ["Pattern","SubPattern","Tokenizer","parse","parse_template",
- "expand_template"]
-
SPECIAL_CHARS = ".\\[{()*+?^$|"
REPEAT_CHARS = "*+?{"
WHITESPACE = tuple(" \t\n\r\v\f")
ESCAPES = {
- r"\a": (LITERAL, 7),
- r"\b": (LITERAL, 8),
- r"\f": (LITERAL, 12),
- r"\n": (LITERAL, 10),
- r"\r": (LITERAL, 13),
- r"\t": (LITERAL, 9),
- r"\v": (LITERAL, 11),
+ r"\a": (LITERAL, ord("\a")),
+ r"\b": (LITERAL, ord("\b")),
+ r"\f": (LITERAL, ord("\f")),
+ r"\n": (LITERAL, ord("\n")),
+ r"\r": (LITERAL, ord("\r")),
+ r"\t": (LITERAL, ord("\t")),
+ r"\v": (LITERAL, ord("\v")),
r"\\": (LITERAL, ord("\\"))
}
"u": SRE_FLAG_UNICODE,
}
+# figure out best way to convert hex/octal numbers to integers
+try:
+ int("10", 8)
+ atoi = int # 2.0 and later
+except TypeError:
+ atoi = string.atoi # 1.5.2
+
class Pattern:
# master pattern object. keeps track of global attributes
def __init__(self):
def _group(escape, groups):
# check if the escape string represents a valid group
try:
- gid = int(escape[1:])
+ gid = atoi(escape[1:])
if gid and gid < groups:
return gid
except ValueError:
escape = escape[2:]
if len(escape) != 2:
raise error, "bogus escape: %s" % repr("\\" + escape)
- return LITERAL, int(escape, 16) & 0xff
+ return LITERAL, atoi(escape, 16) & 0xff
elif str(escape[1:2]) in OCTDIGITS:
# octal escape (up to three digits)
while source.next in OCTDIGITS and len(escape) < 5:
escape = escape + source.get()
escape = escape[1:]
- return LITERAL, int(escape, 8) & 0xff
+ return LITERAL, atoi(escape, 8) & 0xff
if len(escape) == 2:
return LITERAL, ord(escape[1])
except ValueError:
escape = escape + source.get()
if len(escape) != 4:
raise ValueError
- return LITERAL, int(escape[2:], 16) & 0xff
+ return LITERAL, atoi(escape[2:], 16) & 0xff
elif escape[1:2] == "0":
# octal escape
while source.next in OCTDIGITS and len(escape) < 4:
escape = escape + source.get()
- return LITERAL, int(escape[1:], 8) & 0xff
+ return LITERAL, atoi(escape[1:], 8) & 0xff
elif escape[1:2] in DIGITS:
# octal escape *or* decimal group reference (sigh)
here = source.tell()
source.next in OCTDIGITS):
# got three octal digits; this is an octal escape
escape = escape + source.get()
- return LITERAL, int(escape[1:], 8) & 0xff
+ return LITERAL, atoi(escape[1:], 8) & 0xff
# got at least one decimal digit; this is a group reference
group = _group(escape, state.groups)
if group:
source.seek(here)
continue
if lo:
- min = int(lo)
+ min = atoi(lo)
if hi:
- max = int(hi)
+ max = atoi(hi)
if max < min:
raise error, "bad repeat interval"
else:
if not name:
raise error, "bad group name"
try:
- index = int(name)
+ index = atoi(name)
except ValueError:
if not isname(name):
raise error, "bad character in group name"
break
if not code:
this = this[1:]
- code = LITERAL, int(this[-6:], 8) & 0xff
+ code = LITERAL, atoi(this[-6:], 8) & 0xff
a(code)
else:
try:
if s is None:
raise error, "empty group"
a(s)
- return sep.join(p)
+ return string.join(p, sep)