Kaydet (Commit) 018b0eb0 authored tarafından Guido van Rossum's avatar Guido van Rossum

Partially implement SF feature request 444708.

Add optional arg to string methods strip(), lstrip(), rstrip().
The optional arg specifies characters to delete.

Also for UserString.

Still to do:

- Misc/NEWS
- LaTeX docs (I did the docstrings though)
- Unicode methods, and Unicode support in the string methods.
üst 9344b148
...@@ -108,7 +108,7 @@ class UserString: ...@@ -108,7 +108,7 @@ class UserString:
def join(self, seq): return self.data.join(seq) def join(self, seq): return self.data.join(seq)
def ljust(self, width): return self.__class__(self.data.ljust(width)) def ljust(self, width): return self.__class__(self.data.ljust(width))
def lower(self): return self.__class__(self.data.lower()) def lower(self): return self.__class__(self.data.lower())
def lstrip(self): return self.__class__(self.data.lstrip()) def lstrip(self, sep=None): return self.__class__(self.data.lstrip(sep))
def replace(self, old, new, maxsplit=-1): def replace(self, old, new, maxsplit=-1):
return self.__class__(self.data.replace(old, new, maxsplit)) return self.__class__(self.data.replace(old, new, maxsplit))
def rfind(self, sub, start=0, end=sys.maxint): def rfind(self, sub, start=0, end=sys.maxint):
...@@ -116,13 +116,13 @@ class UserString: ...@@ -116,13 +116,13 @@ class UserString:
def rindex(self, sub, start=0, end=sys.maxint): def rindex(self, sub, start=0, end=sys.maxint):
return self.data.rindex(sub, start, end) return self.data.rindex(sub, start, end)
def rjust(self, width): return self.__class__(self.data.rjust(width)) def rjust(self, width): return self.__class__(self.data.rjust(width))
def rstrip(self): return self.__class__(self.data.rstrip()) def rstrip(self, sep=None): return self.__class__(self.data.rstrip(sep))
def split(self, sep=None, maxsplit=-1): def split(self, sep=None, maxsplit=-1):
return self.data.split(sep, maxsplit) return self.data.split(sep, maxsplit)
def splitlines(self, keepends=0): return self.data.splitlines(keepends) def splitlines(self, keepends=0): return self.data.splitlines(keepends)
def startswith(self, prefix, start=0, end=sys.maxint): def startswith(self, prefix, start=0, end=sys.maxint):
return self.data.startswith(prefix, start, end) return self.data.startswith(prefix, start, end)
def strip(self): return self.__class__(self.data.strip()) def strip(self, sep=None): return self.__class__(self.data.strip(sep))
def swapcase(self): return self.__class__(self.data.swapcase()) def swapcase(self): return self.__class__(self.data.swapcase())
def title(self): return self.__class__(self.data.title()) def title(self): return self.__class__(self.data.title())
def translate(self, *args): def translate(self, *args):
......
...@@ -163,6 +163,18 @@ def run_method_tests(test): ...@@ -163,6 +163,18 @@ def run_method_tests(test):
test('rstrip', ' hello ', ' hello') test('rstrip', ' hello ', ' hello')
test('strip', 'hello', 'hello') test('strip', 'hello', 'hello')
# strip/lstrip/rstrip with None arg
test('strip', ' hello ', 'hello', None)
test('lstrip', ' hello ', 'hello ', None)
test('rstrip', ' hello ', ' hello', None)
test('strip', 'hello', 'hello', None)
# strip/lstrip/rstrip with real arg
test('strip', 'xyzzyhelloxyzzy', 'hello', 'xyz')
test('lstrip', 'xyzzyhelloxyzzy', 'helloxyzzy', 'xyz')
test('rstrip', 'xyzzyhelloxyzzy', 'xyzzyhello', 'xyz')
test('strip', 'hello', 'hello', 'xyz')
test('swapcase', 'HeLLo cOmpUteRs', 'hEllO CoMPuTErS') test('swapcase', 'HeLLo cOmpUteRs', 'hEllO CoMPuTErS')
test('translate', 'xyzabcdef', 'xyzxyz', transtable, 'def') test('translate', 'xyzabcdef', 'xyzxyz', transtable, 'def')
......
...@@ -1002,6 +1002,9 @@ static PyBufferProcs string_as_buffer = { ...@@ -1002,6 +1002,9 @@ static PyBufferProcs string_as_buffer = {
#define RIGHTSTRIP 1 #define RIGHTSTRIP 1
#define BOTHSTRIP 2 #define BOTHSTRIP 2
/* Arrays indexed by above */
static const char *stripname[] = {"lstrip", "rstrip", "strip"};
static PyObject * static PyObject *
split_whitespace(const char *s, int len, int maxsplit) split_whitespace(const char *s, int len, int maxsplit)
...@@ -1376,6 +1379,39 @@ string_rindex(PyStringObject *self, PyObject *args) ...@@ -1376,6 +1379,39 @@ string_rindex(PyStringObject *self, PyObject *args)
} }
static PyObject *
do_xstrip(PyStringObject *self, int striptype, PyObject *sepobj)
{
char *s = PyString_AS_STRING(self);
int len = PyString_GET_SIZE(self);
char *sep = PyString_AS_STRING(sepobj);
int seplen = PyString_GET_SIZE(sepobj);
int i, j;
i = 0;
if (striptype != RIGHTSTRIP) {
while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) {
i++;
}
}
j = len;
if (striptype != LEFTSTRIP) {
do {
j--;
} while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen));
j++;
}
if (i == 0 && j == len && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*)self;
}
else
return PyString_FromStringAndSize(s+i, j-i);
}
static PyObject * static PyObject *
do_strip(PyStringObject *self, int striptype) do_strip(PyStringObject *self, int striptype)
{ {
...@@ -1406,40 +1442,75 @@ do_strip(PyStringObject *self, int striptype) ...@@ -1406,40 +1442,75 @@ do_strip(PyStringObject *self, int striptype)
} }
static PyObject *
do_argstrip(PyStringObject *self, int striptype, PyObject *args)
{
PyObject *sep = NULL;
if (!PyArg_ParseTuple(args, "|O:[lr]strip", &sep))
return NULL;
if (sep != NULL && sep != Py_None) {
/* XXX What about Unicode? */
if (!PyString_Check(sep)) {
PyErr_Format(PyExc_TypeError,
"%s arg must be None or string",
stripname[striptype]);
return NULL;
}
return do_xstrip(self, striptype, sep);
}
return do_strip(self, striptype);
}
static char strip__doc__[] = static char strip__doc__[] =
"S.strip() -> string\n\ "S.strip([sep]) -> string\n\
\n\ \n\
Return a copy of the string S with leading and trailing\n\ Return a copy of the string S with leading and trailing\n\
whitespace removed."; whitespace removed.\n\
If sep is given and not None, remove characters in sep instead.";
static PyObject * static PyObject *
string_strip(PyStringObject *self) string_strip(PyStringObject *self, PyObject *args)
{ {
return do_strip(self, BOTHSTRIP); if (PyTuple_GET_SIZE(args) == 0)
return do_strip(self, BOTHSTRIP); /* Common case */
else
return do_argstrip(self, BOTHSTRIP, args);
} }
static char lstrip__doc__[] = static char lstrip__doc__[] =
"S.lstrip() -> string\n\ "S.lstrip([sep]) -> string\n\
\n\ \n\
Return a copy of the string S with leading whitespace removed."; Return a copy of the string S with leading whitespace removed.\n\
If sep is given and not None, remove characters in sep instead.";
static PyObject * static PyObject *
string_lstrip(PyStringObject *self) string_lstrip(PyStringObject *self, PyObject *args)
{ {
return do_strip(self, LEFTSTRIP); if (PyTuple_GET_SIZE(args) == 0)
return do_strip(self, LEFTSTRIP); /* Common case */
else
return do_argstrip(self, LEFTSTRIP, args);
} }
static char rstrip__doc__[] = static char rstrip__doc__[] =
"S.rstrip() -> string\n\ "S.rstrip([sep]) -> string\n\
\n\ \n\
Return a copy of the string S with trailing whitespace removed."; Return a copy of the string S with trailing whitespace removed.\n\
If sep is given and not None, remove characters in sep instead.";
static PyObject * static PyObject *
string_rstrip(PyStringObject *self) string_rstrip(PyStringObject *self, PyObject *args)
{ {
return do_strip(self, RIGHTSTRIP); if (PyTuple_GET_SIZE(args) == 0)
return do_strip(self, RIGHTSTRIP); /* Common case */
else
return do_argstrip(self, RIGHTSTRIP, args);
} }
...@@ -2644,13 +2715,13 @@ string_methods[] = { ...@@ -2644,13 +2715,13 @@ string_methods[] = {
{"endswith", (PyCFunction)string_endswith, METH_VARARGS, endswith__doc__}, {"endswith", (PyCFunction)string_endswith, METH_VARARGS, endswith__doc__},
{"find", (PyCFunction)string_find, METH_VARARGS, find__doc__}, {"find", (PyCFunction)string_find, METH_VARARGS, find__doc__},
{"index", (PyCFunction)string_index, METH_VARARGS, index__doc__}, {"index", (PyCFunction)string_index, METH_VARARGS, index__doc__},
{"lstrip", (PyCFunction)string_lstrip, METH_NOARGS, lstrip__doc__}, {"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__},
{"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__}, {"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__},
{"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__}, {"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__},
{"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__}, {"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__},
{"rstrip", (PyCFunction)string_rstrip, METH_NOARGS, rstrip__doc__}, {"rstrip", (PyCFunction)string_rstrip, METH_VARARGS, rstrip__doc__},
{"startswith", (PyCFunction)string_startswith, METH_VARARGS, startswith__doc__}, {"startswith", (PyCFunction)string_startswith, METH_VARARGS, startswith__doc__},
{"strip", (PyCFunction)string_strip, METH_NOARGS, strip__doc__}, {"strip", (PyCFunction)string_strip, METH_VARARGS, strip__doc__},
{"swapcase", (PyCFunction)string_swapcase, METH_NOARGS, swapcase__doc__}, {"swapcase", (PyCFunction)string_swapcase, METH_NOARGS, swapcase__doc__},
{"translate", (PyCFunction)string_translate, METH_VARARGS, translate__doc__}, {"translate", (PyCFunction)string_translate, METH_VARARGS, translate__doc__},
{"title", (PyCFunction)string_title, METH_NOARGS, title__doc__}, {"title", (PyCFunction)string_title, METH_NOARGS, title__doc__},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment