From 7b7c5786161d9d443d13f56276620519587a2624 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 14 Mar 1997 04:13:56 +0000 Subject: Add optional 4th argument to [r]find and [r]index (end of slice). --- Doc/lib/libstring.tex | 17 ++++++++++------- Doc/libstring.tex | 17 ++++++++++------- Lib/string.py | 36 ++++++++++++++++++++++++++---------- Lib/stringold.py | 36 ++++++++++++++++++++++++++---------- Modules/stropmodule.c | 36 +++++++++++++++++++++++++++--------- 5 files changed, 99 insertions(+), 43 deletions(-) diff --git a/Doc/lib/libstring.tex b/Doc/lib/libstring.tex index af3fd58..80222c1 100644 --- a/Doc/lib/libstring.tex +++ b/Doc/lib/libstring.tex @@ -103,24 +103,27 @@ This doesn't understand other non-printing characters or escape sequences. \end{funcdesc} -\begin{funcdesc}{find}{s\, sub\optional{\, start}} -Return the lowest index in \var{s} not smaller than \var{start} where the -substring \var{sub} is found. Return \code{-1} when \var{sub} -does not occur as a substring of \var{s} with index at least \var{start}. +\begin{funcdesc}{find}{s\, sub\optional{\, start\optional{\,end}}} +Return the lowest index in \var{s} not smaller than \var{start} and not +greater than \var{end} where the substring \var{sub} is found. Return +\code{-1} when \var{sub} does not occur as a substring of \var{s} with +index at least \var{start} and less than \var{end}. If \var{start} is omitted, it defaults to \code{0}. If \var{start} is negative, \code{len(\var{s})} is added. +If \var{end} is omitted, it defaults to \code{len(\var{s})}. If +\var{end} is negative, \code{len(\var{s})} is added. \end{funcdesc} -\begin{funcdesc}{rfind}{s\, sub\optional{\, start}} +\begin{funcdesc}{rfind}{s\, sub\optional{\, start\optional{\,end}}} Like \code{find} but find the highest index. \end{funcdesc} -\begin{funcdesc}{index}{s\, sub\optional{\, start}} +\begin{funcdesc}{index}{s\, sub\optional{\, start\optional{\,end}}} Like \code{find} but raise \code{ValueError} when the substring is not found. \end{funcdesc} -\begin{funcdesc}{rindex}{s\, sub\optional{\, start}} +\begin{funcdesc}{rindex}{s\, sub\optional{\, start\optional{\,end}}} Like \code{rfind} but raise \code{ValueError} when the substring is not found. \end{funcdesc} diff --git a/Doc/libstring.tex b/Doc/libstring.tex index af3fd58..80222c1 100644 --- a/Doc/libstring.tex +++ b/Doc/libstring.tex @@ -103,24 +103,27 @@ This doesn't understand other non-printing characters or escape sequences. \end{funcdesc} -\begin{funcdesc}{find}{s\, sub\optional{\, start}} -Return the lowest index in \var{s} not smaller than \var{start} where the -substring \var{sub} is found. Return \code{-1} when \var{sub} -does not occur as a substring of \var{s} with index at least \var{start}. +\begin{funcdesc}{find}{s\, sub\optional{\, start\optional{\,end}}} +Return the lowest index in \var{s} not smaller than \var{start} and not +greater than \var{end} where the substring \var{sub} is found. Return +\code{-1} when \var{sub} does not occur as a substring of \var{s} with +index at least \var{start} and less than \var{end}. If \var{start} is omitted, it defaults to \code{0}. If \var{start} is negative, \code{len(\var{s})} is added. +If \var{end} is omitted, it defaults to \code{len(\var{s})}. If +\var{end} is negative, \code{len(\var{s})} is added. \end{funcdesc} -\begin{funcdesc}{rfind}{s\, sub\optional{\, start}} +\begin{funcdesc}{rfind}{s\, sub\optional{\, start\optional{\,end}}} Like \code{find} but find the highest index. \end{funcdesc} -\begin{funcdesc}{index}{s\, sub\optional{\, start}} +\begin{funcdesc}{index}{s\, sub\optional{\, start\optional{\,end}}} Like \code{find} but raise \code{ValueError} when the substring is not found. \end{funcdesc} -\begin{funcdesc}{rindex}{s\, sub\optional{\, start}} +\begin{funcdesc}{rindex}{s\, sub\optional{\, start\optional{\,end}}} Like \code{rfind} but raise \code{ValueError} when the substring is not found. \end{funcdesc} diff --git a/Lib/string.py b/Lib/string.py index 687518d..d3ab88f 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -120,15 +120,17 @@ def joinfields(words, sep = ' '): return res[len(sep):] # Find substring, raise exception if not found -def index(s, sub, i = 0): - res = find(s, sub, i) +def index(s, sub, i = 0, last=None): + if last == None: last = len(s) + res = find(s, sub, i, last) if res < 0: raise ValueError, 'substring not found in string.index' return res # Find last substring, raise exception if not found -def rindex(s, sub, i = 0): - res = rfind(s, sub, i) +def rindex(s, sub, i = 0, last=None): + if last == None: last = len(s) + res = rfind(s, sub, i, last) if res < 0: raise ValueError, 'substring not found in string.index' return res @@ -149,20 +151,34 @@ def count(s, sub, i = 0): return r # Find substring, return -1 if not found -def find(s, sub, i = 0): - if i < 0: i = max(0, i + len(s)) +def find(s, sub, i = 0, last=None): + Slen = len(s) # cache this value, for speed + if last == None: + last = Slen + elif last < 0: + last = max(0, last + Slen) + elif last > Slen: + last = Slen + if i < 0: i = max(0, i + Slen) n = len(sub) - m = len(s) + 1 - n + m = last + 1 - n while i < m: if sub == s[i:i+n]: return i i = i+1 return -1 # Find last substring, return -1 if not found -def rfind(s, sub, i = 0): - if i < 0: i = max(0, i + len(s)) +def rfind(s, sub, i = 0, last=None): + Slen = len(s) # cache this value, for speed + if last == None: + last = Slen + elif last < 0: + last = max(0, last + Slen) + elif last > Slen: + last = Slen + if i < 0: i = max(0, i + Slen) n = len(sub) - m = len(s) + 1 - n + m = last + 1 - n r = -1 while i < m: if sub == s[i:i+n]: r = i diff --git a/Lib/stringold.py b/Lib/stringold.py index 687518d..d3ab88f 100644 --- a/Lib/stringold.py +++ b/Lib/stringold.py @@ -120,15 +120,17 @@ def joinfields(words, sep = ' '): return res[len(sep):] # Find substring, raise exception if not found -def index(s, sub, i = 0): - res = find(s, sub, i) +def index(s, sub, i = 0, last=None): + if last == None: last = len(s) + res = find(s, sub, i, last) if res < 0: raise ValueError, 'substring not found in string.index' return res # Find last substring, raise exception if not found -def rindex(s, sub, i = 0): - res = rfind(s, sub, i) +def rindex(s, sub, i = 0, last=None): + if last == None: last = len(s) + res = rfind(s, sub, i, last) if res < 0: raise ValueError, 'substring not found in string.index' return res @@ -149,20 +151,34 @@ def count(s, sub, i = 0): return r # Find substring, return -1 if not found -def find(s, sub, i = 0): - if i < 0: i = max(0, i + len(s)) +def find(s, sub, i = 0, last=None): + Slen = len(s) # cache this value, for speed + if last == None: + last = Slen + elif last < 0: + last = max(0, last + Slen) + elif last > Slen: + last = Slen + if i < 0: i = max(0, i + Slen) n = len(sub) - m = len(s) + 1 - n + m = last + 1 - n while i < m: if sub == s[i:i+n]: return i i = i+1 return -1 # Find last substring, return -1 if not found -def rfind(s, sub, i = 0): - if i < 0: i = max(0, i + len(s)) +def rfind(s, sub, i = 0, last=None): + Slen = len(s) # cache this value, for speed + if last == None: + last = Slen + elif last < 0: + last = max(0, last + Slen) + elif last > Slen: + last = Slen + if i < 0: i = max(0, i + Slen) n = len(sub) - m = len(s) + 1 - n + m = last + 1 - n r = -1 while i < m: if sub == s[i:i+n]: r = i diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c index 8ddf37d..9594837 100644 --- a/Modules/stropmodule.c +++ b/Modules/stropmodule.c @@ -33,6 +33,12 @@ PERFORMANCE OF THIS SOFTWARE. #include "Python.h" +#ifdef HAVE_LIMITS_H +#include +#else +#define INT_MAX 2147483647 +#endif + #include /* XXX This file assumes that the is*() functions XXX are defined for all 8-bit characters! */ @@ -286,11 +292,17 @@ strop_find(self, args) PyObject *args; { char *s, *sub; - int len, n, i = 0; + int len, n, i = 0, last = INT_MAX; - if (!PyArg_ParseTuple(args, "s#s#|i", &s, &len, &sub, &n, &i)) + if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last)) return NULL; + if (last > len) + last = len; + if (last < 0) + last += len; + if (last < 0) + last = 0; if (i < 0) i += len; if (i < 0) @@ -299,8 +311,8 @@ strop_find(self, args) if (n == 0) return PyInt_FromLong((long)i); - len -= n; - for (; i <= len; ++i) + last -= n; + for (; i <= last; ++i) if (s[i] == sub[0] && (n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0)) return PyInt_FromLong((long)i); @@ -316,20 +328,26 @@ strop_rfind(self, args) { char *s, *sub; int len, n, j; - int i = 0; + int i = 0, last = INT_MAX; - if (!PyArg_ParseTuple(args, "s#s#|i", &s, &len, &sub, &n, &i)) + if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last)) return NULL; + if (last > len) + last = len; + if (last < 0) + last += len; + if (last < 0) + last = 0; if (i < 0) i += len; if (i < 0) i = 0; if (n == 0) - return PyInt_FromLong((long)len); + return PyInt_FromLong((long)last); - for (j = len-n; j >= i; --j) + for (j = last-n; j >= i; --j) if (s[j] == sub[0] && (n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0)) return PyInt_FromLong((long)j); @@ -663,7 +681,7 @@ strop_atof(self, args) errno = 0; PyFPE_START_PROTECT("strop_atof", return 0) x = strtod(s, &end); - PyFPE_END_PROTECT + PyFPE_END_PROTECT(x) while (*end && isspace(Py_CHARMASK(*end))) end++; if (*end != '\0') { -- cgit v0.12