Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7b7c578

Browse files
committed
Add optional 4th argument to [r]find and [r]index (end of slice).
1 parent 612316f commit 7b7c578

5 files changed

Lines changed: 99 additions & 43 deletions

File tree

Doc/lib/libstring.tex

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,27 @@ \section{Standard Module \sectcode{string}}
103103
sequences.
104104
\end{funcdesc}
105105

106-
\begin{funcdesc}{find}{s\, sub\optional{\, start}}
107-
Return the lowest index in \var{s} not smaller than \var{start} where the
108-
substring \var{sub} is found. Return \code{-1} when \var{sub}
109-
does not occur as a substring of \var{s} with index at least \var{start}.
106+
\begin{funcdesc}{find}{s\, sub\optional{\, start\optional{\,end}}}
107+
Return the lowest index in \var{s} not smaller than \var{start} and not
108+
greater than \var{end} where the substring \var{sub} is found. Return
109+
\code{-1} when \var{sub} does not occur as a substring of \var{s} with
110+
index at least \var{start} and less than \var{end}.
110111
If \var{start} is omitted, it defaults to \code{0}. If \var{start} is
111112
negative, \code{len(\var{s})} is added.
113+
If \var{end} is omitted, it defaults to \code{len(\var{s})}. If
114+
\var{end} is negative, \code{len(\var{s})} is added.
112115
\end{funcdesc}
113116

114-
\begin{funcdesc}{rfind}{s\, sub\optional{\, start}}
117+
\begin{funcdesc}{rfind}{s\, sub\optional{\, start\optional{\,end}}}
115118
Like \code{find} but find the highest index.
116119
\end{funcdesc}
117120

118-
\begin{funcdesc}{index}{s\, sub\optional{\, start}}
121+
\begin{funcdesc}{index}{s\, sub\optional{\, start\optional{\,end}}}
119122
Like \code{find} but raise \code{ValueError} when the substring is
120123
not found.
121124
\end{funcdesc}
122125

123-
\begin{funcdesc}{rindex}{s\, sub\optional{\, start}}
126+
\begin{funcdesc}{rindex}{s\, sub\optional{\, start\optional{\,end}}}
124127
Like \code{rfind} but raise \code{ValueError} when the substring is
125128
not found.
126129
\end{funcdesc}

Doc/libstring.tex

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,27 @@ \section{Standard Module \sectcode{string}}
103103
sequences.
104104
\end{funcdesc}
105105

106-
\begin{funcdesc}{find}{s\, sub\optional{\, start}}
107-
Return the lowest index in \var{s} not smaller than \var{start} where the
108-
substring \var{sub} is found. Return \code{-1} when \var{sub}
109-
does not occur as a substring of \var{s} with index at least \var{start}.
106+
\begin{funcdesc}{find}{s\, sub\optional{\, start\optional{\,end}}}
107+
Return the lowest index in \var{s} not smaller than \var{start} and not
108+
greater than \var{end} where the substring \var{sub} is found. Return
109+
\code{-1} when \var{sub} does not occur as a substring of \var{s} with
110+
index at least \var{start} and less than \var{end}.
110111
If \var{start} is omitted, it defaults to \code{0}. If \var{start} is
111112
negative, \code{len(\var{s})} is added.
113+
If \var{end} is omitted, it defaults to \code{len(\var{s})}. If
114+
\var{end} is negative, \code{len(\var{s})} is added.
112115
\end{funcdesc}
113116

114-
\begin{funcdesc}{rfind}{s\, sub\optional{\, start}}
117+
\begin{funcdesc}{rfind}{s\, sub\optional{\, start\optional{\,end}}}
115118
Like \code{find} but find the highest index.
116119
\end{funcdesc}
117120

118-
\begin{funcdesc}{index}{s\, sub\optional{\, start}}
121+
\begin{funcdesc}{index}{s\, sub\optional{\, start\optional{\,end}}}
119122
Like \code{find} but raise \code{ValueError} when the substring is
120123
not found.
121124
\end{funcdesc}
122125

123-
\begin{funcdesc}{rindex}{s\, sub\optional{\, start}}
126+
\begin{funcdesc}{rindex}{s\, sub\optional{\, start\optional{\,end}}}
124127
Like \code{rfind} but raise \code{ValueError} when the substring is
125128
not found.
126129
\end{funcdesc}

Lib/string.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,17 @@ def joinfields(words, sep = ' '):
120120
return res[len(sep):]
121121

122122
# Find substring, raise exception if not found
123-
def index(s, sub, i = 0):
124-
res = find(s, sub, i)
123+
def index(s, sub, i = 0, last=None):
124+
if last == None: last = len(s)
125+
res = find(s, sub, i, last)
125126
if res < 0:
126127
raise ValueError, 'substring not found in string.index'
127128
return res
128129

129130
# Find last substring, raise exception if not found
130-
def rindex(s, sub, i = 0):
131-
res = rfind(s, sub, i)
131+
def rindex(s, sub, i = 0, last=None):
132+
if last == None: last = len(s)
133+
res = rfind(s, sub, i, last)
132134
if res < 0:
133135
raise ValueError, 'substring not found in string.index'
134136
return res
@@ -149,20 +151,34 @@ def count(s, sub, i = 0):
149151
return r
150152

151153
# Find substring, return -1 if not found
152-
def find(s, sub, i = 0):
153-
if i < 0: i = max(0, i + len(s))
154+
def find(s, sub, i = 0, last=None):
155+
Slen = len(s) # cache this value, for speed
156+
if last == None:
157+
last = Slen
158+
elif last < 0:
159+
last = max(0, last + Slen)
160+
elif last > Slen:
161+
last = Slen
162+
if i < 0: i = max(0, i + Slen)
154163
n = len(sub)
155-
m = len(s) + 1 - n
164+
m = last + 1 - n
156165
while i < m:
157166
if sub == s[i:i+n]: return i
158167
i = i+1
159168
return -1
160169

161170
# Find last substring, return -1 if not found
162-
def rfind(s, sub, i = 0):
163-
if i < 0: i = max(0, i + len(s))
171+
def rfind(s, sub, i = 0, last=None):
172+
Slen = len(s) # cache this value, for speed
173+
if last == None:
174+
last = Slen
175+
elif last < 0:
176+
last = max(0, last + Slen)
177+
elif last > Slen:
178+
last = Slen
179+
if i < 0: i = max(0, i + Slen)
164180
n = len(sub)
165-
m = len(s) + 1 - n
181+
m = last + 1 - n
166182
r = -1
167183
while i < m:
168184
if sub == s[i:i+n]: r = i

Lib/stringold.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,17 @@ def joinfields(words, sep = ' '):
120120
return res[len(sep):]
121121

122122
# Find substring, raise exception if not found
123-
def index(s, sub, i = 0):
124-
res = find(s, sub, i)
123+
def index(s, sub, i = 0, last=None):
124+
if last == None: last = len(s)
125+
res = find(s, sub, i, last)
125126
if res < 0:
126127
raise ValueError, 'substring not found in string.index'
127128
return res
128129

129130
# Find last substring, raise exception if not found
130-
def rindex(s, sub, i = 0):
131-
res = rfind(s, sub, i)
131+
def rindex(s, sub, i = 0, last=None):
132+
if last == None: last = len(s)
133+
res = rfind(s, sub, i, last)
132134
if res < 0:
133135
raise ValueError, 'substring not found in string.index'
134136
return res
@@ -149,20 +151,34 @@ def count(s, sub, i = 0):
149151
return r
150152

151153
# Find substring, return -1 if not found
152-
def find(s, sub, i = 0):
153-
if i < 0: i = max(0, i + len(s))
154+
def find(s, sub, i = 0, last=None):
155+
Slen = len(s) # cache this value, for speed
156+
if last == None:
157+
last = Slen
158+
elif last < 0:
159+
last = max(0, last + Slen)
160+
elif last > Slen:
161+
last = Slen
162+
if i < 0: i = max(0, i + Slen)
154163
n = len(sub)
155-
m = len(s) + 1 - n
164+
m = last + 1 - n
156165
while i < m:
157166
if sub == s[i:i+n]: return i
158167
i = i+1
159168
return -1
160169

161170
# Find last substring, return -1 if not found
162-
def rfind(s, sub, i = 0):
163-
if i < 0: i = max(0, i + len(s))
171+
def rfind(s, sub, i = 0, last=None):
172+
Slen = len(s) # cache this value, for speed
173+
if last == None:
174+
last = Slen
175+
elif last < 0:
176+
last = max(0, last + Slen)
177+
elif last > Slen:
178+
last = Slen
179+
if i < 0: i = max(0, i + Slen)
164180
n = len(sub)
165-
m = len(s) + 1 - n
181+
m = last + 1 - n
166182
r = -1
167183
while i < m:
168184
if sub == s[i:i+n]: r = i

Modules/stropmodule.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ PERFORMANCE OF THIS SOFTWARE.
3333

3434
#include "Python.h"
3535

36+
#ifdef HAVE_LIMITS_H
37+
#include <limits.h>
38+
#else
39+
#define INT_MAX 2147483647
40+
#endif
41+
3642
#include <ctype.h>
3743
/* XXX This file assumes that the <ctype.h> is*() functions
3844
XXX are defined for all 8-bit characters! */
@@ -286,11 +292,17 @@ strop_find(self, args)
286292
PyObject *args;
287293
{
288294
char *s, *sub;
289-
int len, n, i = 0;
295+
int len, n, i = 0, last = INT_MAX;
290296

291-
if (!PyArg_ParseTuple(args, "s#s#|i", &s, &len, &sub, &n, &i))
297+
if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last))
292298
return NULL;
293299

300+
if (last > len)
301+
last = len;
302+
if (last < 0)
303+
last += len;
304+
if (last < 0)
305+
last = 0;
294306
if (i < 0)
295307
i += len;
296308
if (i < 0)
@@ -299,8 +311,8 @@ strop_find(self, args)
299311
if (n == 0)
300312
return PyInt_FromLong((long)i);
301313

302-
len -= n;
303-
for (; i <= len; ++i)
314+
last -= n;
315+
for (; i <= last; ++i)
304316
if (s[i] == sub[0] &&
305317
(n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0))
306318
return PyInt_FromLong((long)i);
@@ -316,20 +328,26 @@ strop_rfind(self, args)
316328
{
317329
char *s, *sub;
318330
int len, n, j;
319-
int i = 0;
331+
int i = 0, last = INT_MAX;
320332

321-
if (!PyArg_ParseTuple(args, "s#s#|i", &s, &len, &sub, &n, &i))
333+
if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last))
322334
return NULL;
323335

336+
if (last > len)
337+
last = len;
338+
if (last < 0)
339+
last += len;
340+
if (last < 0)
341+
last = 0;
324342
if (i < 0)
325343
i += len;
326344
if (i < 0)
327345
i = 0;
328346

329347
if (n == 0)
330-
return PyInt_FromLong((long)len);
348+
return PyInt_FromLong((long)last);
331349

332-
for (j = len-n; j >= i; --j)
350+
for (j = last-n; j >= i; --j)
333351
if (s[j] == sub[0] &&
334352
(n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0))
335353
return PyInt_FromLong((long)j);
@@ -663,7 +681,7 @@ strop_atof(self, args)
663681
errno = 0;
664682
PyFPE_START_PROTECT("strop_atof", return 0)
665683
x = strtod(s, &end);
666-
PyFPE_END_PROTECT
684+
PyFPE_END_PROTECT(x)
667685
while (*end && isspace(Py_CHARMASK(*end)))
668686
end++;
669687
if (*end != '\0') {

0 commit comments

Comments
 (0)