3
3
#
4
4
# re-compatible interface for the sre matching engine
5
5
#
6
- # Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved.
6
+ # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved.
7
7
#
8
8
# This version of the SRE library can be redistributed under CNRI's
9
9
# Python 1.6 license. For any other use, please contact Secret Labs
14
14
# other compatibility work.
15
15
#
16
16
17
- # FIXME: change all FIXME's to XXX ;-)
18
-
19
17
import sre_compile
20
18
import sre_parse
21
19
20
+ # public symbols
21
+ __all__ = [ "match" , "search" , "sub" , "subn" , "split" , "findall" ,
22
+ "compile" , "purge" , "template" , "escape" , "I" , "L" , "M" , "S" , "X" ,
23
+ "U" , "IGNORECASE" , "LOCALE" , "MULTILINE" , "DOTALL" , "VERBOSE" ,
24
+ "UNICODE" , "error" ]
25
+
26
+ __version__ = "2.1b2"
27
+
28
+ # this module works under 1.5.2 and later. don't use string methods
22
29
import string
23
30
24
31
# flags
25
- I = IGNORECASE = sre_compile .SRE_FLAG_IGNORECASE
26
- L = LOCALE = sre_compile .SRE_FLAG_LOCALE
27
- M = MULTILINE = sre_compile .SRE_FLAG_MULTILINE
28
- S = DOTALL = sre_compile .SRE_FLAG_DOTALL
29
- X = VERBOSE = sre_compile .SRE_FLAG_VERBOSE
32
+ I = IGNORECASE = sre_compile .SRE_FLAG_IGNORECASE # ignore case
33
+ L = LOCALE = sre_compile .SRE_FLAG_LOCALE # assume current 8-bit locale
34
+ U = UNICODE = sre_compile .SRE_FLAG_UNICODE # assume unicode locale
35
+ M = MULTILINE = sre_compile .SRE_FLAG_MULTILINE # make anchors look for newline
36
+ S = DOTALL = sre_compile .SRE_FLAG_DOTALL # make dot match newline
37
+ X = VERBOSE = sre_compile .SRE_FLAG_VERBOSE # ignore whitespace and comments
30
38
31
- # sre extensions (may or may not be in 1.6/2.0 final )
32
- T = TEMPLATE = sre_compile .SRE_FLAG_TEMPLATE
33
- U = UNICODE = sre_compile .SRE_FLAG_UNICODE
39
+ # sre extensions (experimental, don't rely on these )
40
+ T = TEMPLATE = sre_compile .SRE_FLAG_TEMPLATE # disable backtracking
41
+ DEBUG = sre_compile .SRE_FLAG_DEBUG # dump pattern after compilation
34
42
35
43
# sre exception
36
44
error = sre_compile .error
37
45
38
46
# --------------------------------------------------------------------
39
47
# public interface
40
48
41
- # FIXME: add docstrings
42
-
43
49
def match (pattern , string , flags = 0 ):
50
+ """Try to apply the pattern at the start of the string, returning
51
+ a match object, or None if no match was found."""
44
52
return _compile (pattern , flags ).match (string )
45
53
46
54
def search (pattern , string , flags = 0 ):
55
+ """Scan through string looking for a match to the pattern, returning
56
+ a match object, or None if no match was found."""
47
57
return _compile (pattern , flags ).search (string )
48
58
49
59
def sub (pattern , repl , string , count = 0 ):
60
+ """Return the string obtained by replacing the leftmost
61
+ non-overlapping occurrences of the pattern in string by the
62
+ replacement repl"""
50
63
return _compile (pattern , 0 ).sub (repl , string , count )
51
64
52
65
def subn (pattern , repl , string , count = 0 ):
66
+ """Return a 2-tuple containing (new_string, number).
67
+ new_string is the string obtained by replacing the leftmost
68
+ non-overlapping occurrences of the pattern in the source
69
+ string by the replacement repl. number is the number of
70
+ substitutions that were made."""
53
71
return _compile (pattern , 0 ).subn (repl , string , count )
54
72
55
73
def split (pattern , string , maxsplit = 0 ):
74
+ """Split the source string by the occurrences of the pattern,
75
+ returning a list containing the resulting substrings."""
56
76
return _compile (pattern , 0 ).split (string , maxsplit )
57
77
58
78
def findall (pattern , string , maxsplit = 0 ):
79
+ """Return a list of all non-overlapping matches in the string.
80
+
81
+ If one or more groups are present in the pattern, return a
82
+ list of groups; this will be a list of tuples if the pattern
83
+ has more than one group.
84
+
85
+ Empty matches are included in the result."""
59
86
return _compile (pattern , 0 ).findall (string , maxsplit )
60
87
61
88
def compile (pattern , flags = 0 ):
89
+ "Compile a regular expression pattern, returning a pattern object."
62
90
return _compile (pattern , flags )
63
91
64
92
def purge ():
93
+ "Clear the regular expression cache"
65
94
_cache .clear ()
95
+ _cache_repl .clear ()
66
96
67
97
def template (pattern , flags = 0 ):
98
+ "Compile a template pattern, returning a pattern object"
68
99
return _compile (pattern , flags | T )
69
100
70
101
def escape (pattern ):
102
+ "Escape all non-alphanumeric characters in pattern."
71
103
s = list (pattern )
72
104
for i in range (len (pattern )):
73
105
c = pattern [i ]
@@ -82,6 +114,8 @@ def escape(pattern):
82
114
# internals
83
115
84
116
_cache = {}
117
+ _cache_repl = {}
118
+
85
119
_MAXCACHE = 100
86
120
87
121
def _join (seq , sep ):
@@ -105,6 +139,21 @@ def _compile(*key):
105
139
_cache [key ] = p
106
140
return p
107
141
142
+ def _compile_repl (* key ):
143
+ # internal: compile replacement pattern
144
+ p = _cache_repl .get (key )
145
+ if p is not None :
146
+ return p
147
+ repl , pattern = key
148
+ try :
149
+ p = sre_parse .parse_template (repl , pattern )
150
+ except error , v :
151
+ raise error , v # invalid expression
152
+ if len (_cache_repl ) >= _MAXCACHE :
153
+ _cache_repl .clear ()
154
+ _cache_repl [key ] = p
155
+ return p
156
+
108
157
def _expand (pattern , match , template ):
109
158
# internal: match.expand implementation hook
110
159
template = sre_parse .parse_template (template , pattern )
@@ -119,7 +168,7 @@ def _subn(pattern, template, string, count=0):
119
168
if callable (template ):
120
169
filter = template
121
170
else :
122
- template = sre_parse . parse_template (template , pattern )
171
+ template = _compile_repl (template , pattern )
123
172
def filter (match , template = template ):
124
173
return sre_parse .expand_template (template , match )
125
174
n = i = 0
@@ -158,7 +207,7 @@ def _split(pattern, string, maxsplit=0):
158
207
continue
159
208
append (string [i :b ])
160
209
if g and b != e :
161
- extend (m .groups ())
210
+ extend (list ( m .groups () ))
162
211
i = e
163
212
n = n + 1
164
213
append (string [i :])
@@ -204,7 +253,7 @@ def scan(self, string):
204
253
break
205
254
action = self .lexicon [m .lastindex ][1 ]
206
255
if callable (action ):
207
- self .match = match
256
+ self .match = m
208
257
action = action (self , m .group ())
209
258
if action is not None :
210
259
append (action )
0 commit comments