📄 stringobject.c
字号:
#else
"S.upper() -> string\n\
\n\
Return a copy of the string S converted to uppercase.";
#endif
static PyObject *
string_upper(PyStringObject *self)
{
char *s = PyString_AS_STRING(self), *s_new;
int i, n = PyString_GET_SIZE(self);
PyObject *new;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
return NULL;
s_new = PyString_AsString(new);
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(*s++);
if (islower(c)) {
*s_new = toupper(c);
} else
*s_new = c;
s_new++;
}
return new;
}
const static char title__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.title() -> string\n\
\n\
Return a titlecased version of S, i.e. words start with uppercase\n\
characters, all remaining cased characters have lowercase.";
#endif
static PyObject*
string_title(PyStringObject *self)
{
char *s = PyString_AS_STRING(self), *s_new;
int i, n = PyString_GET_SIZE(self);
int previous_is_cased = 0;
PyObject *new;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
return NULL;
s_new = PyString_AsString(new);
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(*s++);
if (islower(c)) {
if (!previous_is_cased)
c = toupper(c);
previous_is_cased = 1;
} else if (isupper(c)) {
if (previous_is_cased)
c = tolower(c);
previous_is_cased = 1;
} else
previous_is_cased = 0;
*s_new++ = c;
}
return new;
}
const static char capitalize__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.capitalize() -> string\n\
\n\
Return a copy of the string S with only its first character\n\
capitalized.";
#endif
static PyObject *
string_capitalize(PyStringObject *self)
{
char *s = PyString_AS_STRING(self), *s_new;
int i, n = PyString_GET_SIZE(self);
PyObject *new;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
return NULL;
s_new = PyString_AsString(new);
if (0 < n) {
int c = Py_CHARMASK(*s++);
if (islower(c))
*s_new = toupper(c);
else
*s_new = c;
s_new++;
}
for (i = 1; i < n; i++) {
int c = Py_CHARMASK(*s++);
if (isupper(c))
*s_new = tolower(c);
else
*s_new = c;
s_new++;
}
return new;
}
const static char count__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.count(sub[, start[, end]]) -> int\n\
\n\
Return the number of occurrences of substring sub in string\n\
S[start:end]. Optional arguments start and end are\n\
interpreted as in slice notation.";
#endif
static PyObject *
string_count(PyStringObject *self, PyObject *args)
{
const char *s = PyString_AS_STRING(self), *sub;
int len = PyString_GET_SIZE(self), n;
int i = 0, last = INT_MAX;
int m, r;
PyObject *subobj;
if (!PyArg_ParseTuple(args, "O|O&O&:count", &subobj,
_PyEval_SliceIndex, &i, _PyEval_SliceIndex, &last))
return NULL;
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
n = PyString_GET_SIZE(subobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(subobj)) {
int count;
count = PyUnicode_Count((PyObject *)self, subobj, i, last);
if (count == -1)
return NULL;
else
return PyInt_FromLong((long) count);
}
#endif
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
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;
m = last + 1 - n;
if (n == 0)
return PyInt_FromLong((long) (m-i));
r = 0;
while (i < m) {
if (!memcmp(s+i, sub, n)) {
r++;
i += n;
} else {
i++;
}
}
return PyInt_FromLong((long) r);
}
const static char swapcase__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.swapcase() -> string\n\
\n\
Return a copy of the string S with uppercase characters\n\
converted to lowercase and vice versa.";
#endif
static PyObject *
string_swapcase(PyStringObject *self)
{
char *s = PyString_AS_STRING(self), *s_new;
int i, n = PyString_GET_SIZE(self);
PyObject *new;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
return NULL;
s_new = PyString_AsString(new);
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(*s++);
if (islower(c)) {
*s_new = toupper(c);
}
else if (isupper(c)) {
*s_new = tolower(c);
}
else
*s_new = c;
s_new++;
}
return new;
}
const static char translate__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.translate(table [,deletechars]) -> string\n\
\n\
Return a copy of the string S, where all characters occurring\n\
in the optional argument deletechars are removed, and the\n\
remaining characters have been mapped through the given\n\
translation table, which must be a string of length 256.";
#endif
static PyObject *
string_translate(PyStringObject *self, PyObject *args)
{
register char *input, *output;
register const char *table;
register int i, c, changed = 0;
PyObject *input_obj = (PyObject*)self;
const char *table1, *output_start, *del_table=NULL;
int inlen, tablen, dellen = 0;
PyObject *result;
int trans_table[256];
PyObject *tableobj, *delobj = NULL;
if (!PyArg_ParseTuple(args, "O|O:translate",
&tableobj, &delobj))
return NULL;
if (PyString_Check(tableobj)) {
table1 = PyString_AS_STRING(tableobj);
tablen = PyString_GET_SIZE(tableobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(tableobj)) {
/* Unicode .translate() does not support the deletechars
parameter; instead a mapping to None will cause characters
to be deleted. */
if (delobj != NULL) {
PyErr_SetString(PyExc_TypeError,
"deletions are implemented differently for unicode");
return NULL;
}
return PyUnicode_Translate((PyObject *)self, tableobj, NULL);
}
#endif
else if (PyObject_AsCharBuffer(tableobj, &table1, &tablen))
return NULL;
if (delobj != NULL) {
if (PyString_Check(delobj)) {
del_table = PyString_AS_STRING(delobj);
dellen = PyString_GET_SIZE(delobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(delobj)) {
PyErr_SetString(PyExc_TypeError,
"deletions are implemented differently for unicode");
return NULL;
}
#endif
else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen))
return NULL;
if (tablen != 256) {
PyErr_SetString(PyExc_ValueError,
"translation table must be 256 characters long");
return NULL;
}
}
else {
del_table = NULL;
dellen = 0;
}
table = table1;
inlen = PyString_Size(input_obj);
result = PyString_FromStringAndSize((char *)NULL, inlen);
if (result == NULL)
return NULL;
output_start = output = PyString_AsString(result);
input = PyString_AsString(input_obj);
if (dellen == 0) {
/* If no deletions are required, use faster code */
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
if (Py_CHARMASK((*output++ = table[c])) != c)
changed = 1;
}
if (changed || !PyString_CheckExact(input_obj))
return result;
Py_DECREF(result);
Py_INCREF(input_obj);
return input_obj;
}
for (i = 0; i < 256; i++)
trans_table[i] = Py_CHARMASK(table[i]);
for (i = 0; i < dellen; i++)
trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
if (trans_table[c] != -1)
if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
continue;
changed = 1;
}
if (!changed && PyString_CheckExact(input_obj)) {
Py_DECREF(result);
Py_INCREF(input_obj);
return input_obj;
}
/* Fix the size of the resulting string */
if (inlen > 0)
_PyString_Resize(&result, output - output_start);
return result;
}
/* What follows is used for implementing replace(). Perry Stoll. */
/*
mymemfind
strstr replacement for arbitrary blocks of memory.
Locates the first occurrence in the memory pointed to by MEM of the
contents of memory pointed to by PAT. Returns the index into MEM if
found, or -1 if not found. If len of PAT is greater than length of
MEM, the function returns -1.
*/
static int
mymemfind(const char *mem, int len, const char *pat, int pat_len)
{
register int ii;
/* pattern can not occur in the last pat_len-1 chars */
len -= pat_len;
for (ii = 0; ii <= len; ii++) {
if (mem[ii] == pat[0] && memcmp(&mem[ii], pat, pat_len) == 0) {
return ii;
}
}
return -1;
}
/*
mymemcnt
Return the number of distinct times PAT is found in MEM.
meaning mem=1111 and pat==11 returns 2.
mem=11111 and pat==11 also return 2.
*/
static int
mymemcnt(const char *mem, int len, const char *pat, int pat_len)
{
register int offset = 0;
int nfound = 0;
while (len >= 0) {
offset = mymemfind(mem, len, pat, pat_len);
if (offset == -1)
break;
mem += offset + pat_len;
len -= offset + pat_len;
nfound++;
}
return nfound;
}
/*
mymemreplace
Return a string in which all occurrences of PAT in memory STR are
replaced with SUB.
If length of PAT is less than length of STR or there are no occurrences
of PAT in STR, then the original string is returned. Otherwise, a new
string is allocated here and returned.
on return, out_len is:
the length of output string, or
-1 if the input string is returned, or
unchanged if an error occurs (no memory).
return value is:
the new string allocated locally, or
NULL if an error occurred.
*/
static char *
mymemreplace(const char *str, int len, /* input string */
const char *pat, int pat_len, /* pattern string to find */
const char *sub, int sub_len, /* substitution string */
int count, /* number of replacements */
int *out_len)
{
char *out_s;
char *new_s;
int nfound, offset, new_len;
if (len == 0 || pat_len > len)
goto return_same;
/* find length of output string */
nfound = mymemcnt(str, len, pat, pat_len);
if (count < 0)
count = INT_MAX;
else if (nfound > count)
nfound = count;
if (nfound == 0)
goto return_same;
new_len = len + nfound*(sub_len - pat_len);
if (new_len == 0) {
/* Have to allocate something for the caller to free(). */
out_s = (char *)PyMem_MALLOC(1);
if (out_s == NULL)
return NULL;
out_s[0] = '\0';
}
else {
assert(new_len > 0);
new_s = (char *)PyMem_MALLOC(new_len);
if (new_s == NULL)
return NULL;
out_s = new_s;
for (; count > 0 && len > 0; --count) {
/* find index of next instance of pattern */
offset = mymemfind(str, len, pat, pat_len);
if (offset == -1)
break;
/* copy non matching part of input string */
memcpy(new_s, str, offset);
str += offset + pat_len;
len -= offset + pat_len;
/* copy substitute into the output string */
new_s += offset;
memcpy(new_s, sub, sub_len);
new_s += sub_len;
}
/* copy any remaining values into output string */
if (len > 0)
memcpy(new_s, str, len);
}
*out_len = new_len;
return out_s;
return_same:
*out_len = -1;
return (char *)str; /* cast away const */
}
const static char replace__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.replace (old, new[, maxsplit]) -> string\n\
\n\
Return a copy of string S with all occurrences of substring\n\
old replaced by new. If the optional argument maxsplit is\n\
given, only the first maxsplit occurrences are replaced.";
#endif
static PyObject *
string_replace(PyStringObject *self, PyObject *args)
{
const char *str = PyString_AS_STRING(self), *sub, *repl;
char *new_s;
const int len = PyString_GET_SIZE(self);
int sub_len, repl_len, out_len;
int count = -1;
PyObject *new;
PyObject *subobj, *replobj;
if (!PyArg_ParseTuple(args, "OO|i:replace",
&subobj, &replobj, &count))
return NULL;
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
sub_len = PyString_GET_SIZE(subobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(subobj))
return PyUnicode_Replace((PyObject *)self,
subobj, replobj, count);
#endif
else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len))
return NULL;
if (PyString_Check(replobj)) {
repl = PyString_AS_STRING(replobj);
repl_len = PyString_GET_SIZE(replobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(replobj))
return PyUnicode_Replace((PyObject *)self,
subobj, replobj, count);
#endif
else if (PyObject_AsCharBuffer(replobj, &repl, &repl_len))
return NULL;
if (sub_len <= 0) {
PyErr_SetString(PyExc_ValueError, "empty pattern string");
return NULL;
}
new_s = mymemreplace(str,len,sub,sub_len,repl,repl_len,count,&out_len);
if (new_s == NULL) {
PyErr_NoMemory();
return NULL;
}
if (out_len == -1) {
if (PyString_CheckExact(self)) {
/* we're returning another reference to self */
new = (PyObject*)self;
Py_INCREF(new);
}
else {
new = PyString_FromStringAndSize(str, len);
if (new == NULL)
return NULL;
}
}
else {
new = PyString_FromStringAndSize(new_s, out_len);
PyMem_FREE(new_s);
}
return new;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -