Added 3rd optional argument to translate(), a string of characters to delete.

Added maketrans(), a utility to create a translation table.
This commit is contained in:
Guido van Rossum 1996-07-23 18:12:39 +00:00
parent 4dd0bf92e6
commit ed7253ca50
3 changed files with 106 additions and 29 deletions

View file

@ -254,23 +254,37 @@ def expandtabs(s, tabsize=8):
return res + line return res + line
# Character translation through look-up table. # Character translation through look-up table.
def translate(s, table): def translate(s, table, deletions=""):
if type(table) != type('') or len(table) != 256: if type(table) != type('') or len(table) != 256:
raise TypeError, "translation table must be 256-char string" raise TypeError, "translation table must be 256 characters long"
res = "" res = ""
for c in s: for c in s:
res = res + table[ord(c)] if c not in deletions:
return res res = res + table[ord(c)]
return res
# Capitalize a string, e.g. "aBc dEf" -> "Abc def". # Capitalize a string, e.g. "aBc dEf" -> "Abc def".
def capitalize(s): def capitalize(s):
return upper(s[:1]) + lower(s[1:]) return upper(s[:1]) + lower(s[1:])
# Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def". # Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def".
# See also regsub.capwords(). # See also regsub.capwords().
def capwords(s): def capwords(s):
return join(map(capitalize, split(s))) return join(map(capitalize, split(s)))
# Construct a translation string
_idmapL = None
def maketrans(fromstr, tostr):
if len(fromstr) != len(tostr):
raise ValueError, "maketrans arguments must have same length"
global _idmapL
if not _idmapL:
_idmapL = map(None, _idmap)
L = _idmapL[:]
fromstr = map(ord, fromstr)
for i in range(len(fromstr)):
L[fromstr[i]] = tostr[i]
return joinfields(L, "")
# Try importing optional built-in module "strop" -- if it exists, # Try importing optional built-in module "strop" -- if it exists,
# it redefines some string operations that are 100-1000 times faster. # it redefines some string operations that are 100-1000 times faster.

View file

@ -254,23 +254,37 @@ def expandtabs(s, tabsize=8):
return res + line return res + line
# Character translation through look-up table. # Character translation through look-up table.
def translate(s, table): def translate(s, table, deletions=""):
if type(table) != type('') or len(table) != 256: if type(table) != type('') or len(table) != 256:
raise TypeError, "translation table must be 256-char string" raise TypeError, "translation table must be 256 characters long"
res = "" res = ""
for c in s: for c in s:
res = res + table[ord(c)] if c not in deletions:
return res res = res + table[ord(c)]
return res
# Capitalize a string, e.g. "aBc dEf" -> "Abc def". # Capitalize a string, e.g. "aBc dEf" -> "Abc def".
def capitalize(s): def capitalize(s):
return upper(s[:1]) + lower(s[1:]) return upper(s[:1]) + lower(s[1:])
# Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def". # Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def".
# See also regsub.capwords(). # See also regsub.capwords().
def capwords(s): def capwords(s):
return join(map(capitalize, split(s))) return join(map(capitalize, split(s)))
# Construct a translation string
_idmapL = None
def maketrans(fromstr, tostr):
if len(fromstr) != len(tostr):
raise ValueError, "maketrans arguments must have same length"
global _idmapL
if not _idmapL:
_idmapL = map(None, _idmap)
L = _idmapL[:]
fromstr = map(ord, fromstr)
for i in range(len(fromstr)):
L[fromstr[i]] = tostr[i]
return joinfields(L, "")
# Try importing optional built-in module "strop" -- if it exists, # Try importing optional built-in module "strop" -- if it exists,
# it redefines some string operations that are 100-1000 times faster. # it redefines some string operations that are 100-1000 times faster.

View file

@ -547,30 +547,78 @@ strop_atof(self, args)
} }
static PyObject *
strop_maketrans(self, args)
PyObject *self; /* Not used */
PyObject *args;
{
unsigned char c[256], *from=NULL, *to=NULL;
int i, fromlen=0, tolen=0;
if (PyTuple_Size(args)!=0) {
if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen,
&to, &tolen))
return NULL;
}
if (fromlen!=tolen) {
PyErr_SetString(ValueError,
"maketrans arguments must have same length");
return NULL;
}
for(i=0; i<256; i++)
c[i]=(unsigned char)i;
for(i=0; i<fromlen; i++) {
c[from[i]]=to[i];
}
return PyString_FromStringAndSize((char *)c, 256);
}
static object * static object *
strop_translate(self, args) strop_translate(self, args)
object *self; object *self;
object *args; object *args;
{ {
char *input, *table, *output; char *input, *table, *output, *output_start, *delete=NULL;
int inlen, tablen; int inlen, tablen, dellen;
object *result; PyObject *result;
int i; int i, trans_table[256];
if (!newgetargs(args, "s#s#", &input, &inlen, &table, &tablen)) if (!PyArg_ParseTuple(args, "s#s#|s#", &input, &inlen,
&table, &tablen, &delete, &dellen))
return NULL; return NULL;
if (tablen != 256) { if (tablen != 256) {
err_setstr(ValueError, PyErr_SetString(ValueError,
"translation table must be 256 characters long"); "translation table must be 256 characters long");
return NULL; return NULL;
} }
result = newsizedstringobject((char *)NULL, inlen); for(i=0; i<256; i++)
trans_table[i]=Py_CHARMASK(table[i]);
if (delete!=NULL) {
for(i=0; i<dellen; i++)
trans_table[delete[i]]=-1;
}
result = PyString_FromStringAndSize((char *)NULL, inlen);
if (result == NULL) if (result == NULL)
return NULL; return NULL;
output = getstringvalue(result); output_start = output = PyString_AsString(result);
for (i = 0; i < inlen; i++) { if (delete!=NULL && dellen!=0) {
int c = Py_CHARMASK(*input++); for (i = 0; i < inlen; i++) {
*output++ = table[c]; int c = Py_CHARMASK(*input++);
if (trans_table[c]!=-1)
*output++ = (char)trans_table[c];
}
/* Fix the size of the resulting string */
if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
return NULL;
} else {
/* If no deletions are required, use a faster loop */
for (i = 0; i < inlen; i++) {
int c = Py_CHARMASK(*input++);
*output++ = (char)trans_table[c];
}
} }
return result; return result;
} }
@ -592,6 +640,7 @@ static struct methodlist strop_methods[] = {
{"splitfields", strop_splitfields, 1}, {"splitfields", strop_splitfields, 1},
{"strip", strop_strip}, {"strip", strop_strip},
{"swapcase", strop_swapcase}, {"swapcase", strop_swapcase},
{"maketrans", strop_maketrans, 1},
{"translate", strop_translate, 1}, {"translate", strop_translate, 1},
{"upper", strop_upper}, {"upper", strop_upper},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */