Commit 40256e68 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #335 from undingen/str_replace

Implement str.replace maxreplaces
parents f58caf8c 657557be
...@@ -39,7 +39,7 @@ extern "C" unsigned long PyInt_AsUnsignedLongMask(PyObject* op) noexcept { ...@@ -39,7 +39,7 @@ extern "C" unsigned long PyInt_AsUnsignedLongMask(PyObject* op) noexcept {
extern "C" long PyInt_AsLong(PyObject* op) noexcept { extern "C" long PyInt_AsLong(PyObject* op) noexcept {
// This method should do quite a bit more, including checking tp_as_number->nb_int (or calling __int__?) // This method should do quite a bit more, including checking tp_as_number->nb_int (or calling __int__?)
if (op->cls == int_cls) if (isSubclass(op->cls, int_cls))
return static_cast<BoxedInt*>(op)->n; return static_cast<BoxedInt*>(op)->n;
if (op->cls == long_cls) if (op->cls == long_cls)
......
...@@ -1516,30 +1516,34 @@ Box* strJoin(BoxedString* self, Box* rhs) { ...@@ -1516,30 +1516,34 @@ Box* strJoin(BoxedString* self, Box* rhs) {
} }
Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
RELEASE_ASSERT(_self->cls == str_cls, ""); if (_self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'replace' requires a 'str' object but received a '%s'",
getTypeName(_self));
BoxedString* self = static_cast<BoxedString*>(_self); BoxedString* self = static_cast<BoxedString*>(_self);
RELEASE_ASSERT(_old->cls == str_cls, ""); if (_old->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* old = static_cast<BoxedString*>(_old); BoxedString* old = static_cast<BoxedString*>(_old);
RELEASE_ASSERT(_new->cls == str_cls, ""); if (_new->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* new_ = static_cast<BoxedString*>(_new); BoxedString* new_ = static_cast<BoxedString*>(_new);
Box* _count = _args[0]; Box* _maxreplace = _args[0];
if (!isSubclass(_maxreplace->cls, int_cls))
RELEASE_ASSERT(isSubclass(_count->cls, int_cls), "an integer is required"); raiseExcHelper(TypeError, "an integer is required");
BoxedInt* count = static_cast<BoxedInt*>(_count);
RELEASE_ASSERT(count->n < 0, "'count' argument unsupported");
BoxedString* rtn = new BoxedString(self->s); int max_replaces = static_cast<BoxedInt*>(_maxreplace)->n;
// From http://stackoverflow.com/questions/2896600/how-to-replace-all-occurrences-of-a-character-in-string
size_t start_pos = 0; size_t start_pos = 0;
while ((start_pos = rtn->s.find(old->s, start_pos)) != std::string::npos) { std::string s = self->s;
rtn->s.replace(start_pos, old->s.length(), new_->s); for (int num_replaced = 0; num_replaced < max_replaces || max_replaces < 0; ++num_replaced) {
start_pos = s.find(old->s, start_pos);
if (start_pos == std::string::npos)
break;
s.replace(start_pos, old->s.length(), new_->s);
start_pos += new_->s.length(); // Handles case where 'to' is a substring of 'from' start_pos += new_->s.length(); // Handles case where 'to' is a substring of 'from'
} }
return rtn; return new BoxedString(std::move(s));
} }
Box* strPartition(BoxedString* self, BoxedString* sep) { Box* strPartition(BoxedString* self, BoxedString* sep) {
......
...@@ -63,6 +63,10 @@ for i in ["", "a", "ab", "aa"]: ...@@ -63,6 +63,10 @@ for i in ["", "a", "ab", "aa"]:
print i, j, i.startswith(j), j.startswith(i), i.endswith(j), j.endswith(i), i.find(j), j.find(i), i.rfind(j), j.rfind(i) print i, j, i.startswith(j), j.startswith(i), i.endswith(j), j.endswith(i), i.find(j), j.find(i), i.rfind(j), j.rfind(i)
print "bananananananas".replace("anan", "an") print "bananananananas".replace("anan", "an")
print "bananananananas".replace("anan", "An", 0)
print "bananananananas".replace("anan", "An", -1)
print "bananananananas".replace("anan", "An", 1)
print "bananananananas".replace("anan", "An", 5)
translation_map = [chr(c) for c in xrange(256)] translation_map = [chr(c) for c in xrange(256)]
for c in "aeiou": for c in "aeiou":
......
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