Index: src/org/python/core/PyString.java =================================================================== --- src/org/python/core/PyString.java (revision 4809) +++ src/org/python/core/PyString.java (working copy) @@ -2186,6 +2186,93 @@ } return super.unsupportedopMessage(op, o2); } + + public PyList rsplit(){ + return str_rsplit(null,-1); + } + + public PyList rsplit(String sep) { + return str_rsplit(sep, -1); + } + + public PyList rsplit(String sep, int maxsplit) { + return str_rsplit(sep, maxsplit); + } + + @ExposedMethod(defaults = {"null", "-1"}) + final PyList str_rsplit(String sep, int maxsplit) { + if (sep != null) { + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + PyList list = rsplitfields(sep,maxsplit); + list.reverse(); + return list; + } + PyList list = new PyList(); + char[] chars = string.toCharArray(); + if (maxsplit < 0) + maxsplit = chars.length; + + int splits = 0; + int i = chars.length - 1; + while (i > 0 && splits < maxsplit){ + while(i > 0 && Character.isWhitespace(chars[i])) + i--; + + int next_ws_char = i; + while (next_ws_char > -1 && !Character.isWhitespace(chars[next_ws_char])) + next_ws_char--; + if (next_ws_char == -1) + break; + splits++; + list.add(fromSubstring(next_ws_char+1,i+1)); + i = next_ws_char; + } + + while(i > -1 && Character.isWhitespace(chars[i])) + i--; + if (i > -1) + list.add(fromSubstring(0,i+1)); + //It'd be nice if lists supported a push() method. + // Can't use list.insert(0,foo) because a quadratic time would result. + list.reverse(); + return list; + } + private PyList rsplitfields(String sep, int maxsplit) { + PyList list = new PyList(); + + int length = string.length(); + if (maxsplit < 0) + maxsplit = length + 1; + + int lastbreak = length; + int splits = 0; + int index = length; + int sepLength = sep.length(); + + + if ((sep.length() == 0) && (maxsplit != 0)) { + index = string.lastIndexOf(sep, lastbreak); + list.append(fromSubstring(index /* +sepLength (= 0)*/, lastbreak)); + splits++; + } + + while (splits < maxsplit) { + index = string.lastIndexOf(sep, index-1); + if (index == -1) + break; + if (sep.length() == 0) + index++; + splits++; + list.append(fromSubstring(index+sepLength, lastbreak)); + lastbreak = index; + } + if (lastbreak > -1) { + list.append(fromSubstring(0, lastbreak)); + } + return list; + } } final class StringFormatter Index: Lib/test/string_tests.py =================================================================== --- Lib/test/string_tests.py (revision 4809) +++ Lib/test/string_tests.py (working copy) @@ -185,9 +185,21 @@ self.checkequal(['a', 'b', 'c d'], 'a b c d', 'split', None, 2) self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'split') self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'split', '//') - #self.checkequal(['endcase ', ''], 'endcase test', 'split', 'test') - + #rsplit + self.checkequal(['a', 'b', 'c', 'd'], 'a|b|c|d', 'rsplit', '|') + self.checkequal(['a|b', 'c','d'], 'a|b|c|d', 'rsplit', '|', 2) + self.checkequal(['a b c', 'd'], 'a b c d', 'rsplit', None, 1) + self.checkequal(['a b', 'c', 'd'], 'a b c d', 'rsplit', None, 2) + self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 3) + self.checkequal(['a', 'b', 'c', 'd'], 'a b c d', 'rsplit', None, 4) + self.checkequal(['a b c d'], 'a b c d', 'split', None, 0) + self.checkequal(['a b', 'c','d'], 'a b c d', 'rsplit', None, 2) + self.checkequal(['a', 'b', 'c', 'd'], 'a b c d ', 'rsplit') + self.checkequal(['a', 'b', 'c', 'd'], 'a//b//c//d', 'rsplit', '//') + self.checkequal(['','foo','bar','baz'], '/foo/bar/baz', 'rsplit', "/") self.checkraises(TypeError, 'hello', 'split', 42, 42, 42) + self.checkraises(ValueError, 'hello', 'rsplit', "",42) + self.checkraises(ValueError, 'hello', 'rsplit', "") def test_strip(self): self.checkequal('hello', ' hello ', 'strip')