diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-09-02 11:53:49 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-09-02 11:53:49 -0700 |
commit | 7bf214398f31eb5b6b613346a4214bcb59ea2018 (patch) | |
tree | 947e5cd01d423106ac539aa4c7d95e93fdd0d707 /regex | |
parent | 051128862ae7c5c031b8ddb763848ed264a63746 (diff) | |
parent | 51809b9c7995d8b813f68712b096d23179de3af0 (diff) | |
download | libcore-7bf214398f31eb5b6b613346a4214bcb59ea2018.zip libcore-7bf214398f31eb5b6b613346a4214bcb59ea2018.tar.gz libcore-7bf214398f31eb5b6b613346a4214bcb59ea2018.tar.bz2 |
Merge change 22629 into eclair
* changes:
Fix "whatever".split(".") behavior.
Diffstat (limited to 'regex')
-rw-r--r-- | regex/src/main/java/java/util/regex/Pattern.java | 59 | ||||
-rw-r--r-- | regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java | 56 |
2 files changed, 86 insertions, 29 deletions
diff --git a/regex/src/main/java/java/util/regex/Pattern.java b/regex/src/main/java/java/util/regex/Pattern.java index c058db8..2853bbe 100644 --- a/regex/src/main/java/java/util/regex/Pattern.java +++ b/regex/src/main/java/java/util/regex/Pattern.java @@ -356,28 +356,33 @@ public final class Pattern implements Serializable { } /** - * Splits the given input sequence around occurrences of the {@code Pattern}. - * The function first determines all occurrences of the {@code Pattern} - * inside the input sequence. It then builds an array of the - * "remaining" strings before, in-between, and after these - * occurrences. An additional parameter determines the maximal number of - * entries in the resulting array and the handling of trailing empty - * strings. + * Splits the given input sequence at occurrences of this {@code Pattern}. + * + * If this {@code Pattern} does not occur in the input, the result is an + * array containing the input (converted from a {@code CharSequence} to + * a {@code String}). + * + * Otherwise, the {@code limit} parameter controls the contents of the + * returned array as described below. * * @param inputSeq * the input sequence. * @param limit - * Determines the maximal number of entries in the resulting - * array. + * Determines the maximum number of entries in the resulting + * array, and the treatment of trailing empty strings. * <ul> - * <li>For n > 0, it is guaranteed that the resulting array - * contains at most n entries. + * <li>For n > 0, the resulting array contains at most n + * entries. If this is fewer than the number of matches, the + * final entry will contain all remaining input. * <li>For n < 0, the length of the resulting array is - * exactly the number of occurrences of the {@code Pattern} +1. + * exactly the number of occurrences of the {@code Pattern} + * plus one for the text after the final separator. * All entries are included. - * <li>For n == 0, the length of the resulting array is at most - * the number of occurrences of the {@code Pattern} +1. Empty - * strings at the end of the array are not included. + * <li>For n == 0, the result is as for n < 0, except + * trailing empty strings will not be returned. (Note that + * the case where the input is itself an empty string is + * special, as described above, and the limit parameter does + * not apply there.) * </ul> * * @return the resulting array. @@ -385,6 +390,13 @@ public final class Pattern implements Serializable { * @since Android 1.0 */ public String[] split(CharSequence inputSeq, int limit) { + if (inputSeq.length() == 0) { + // Unlike Perl, which considers the result of splitting the empty + // string to be the empty array, Java returns an array containing + // the empty string. + return new String[] { "" }; + } + int maxLength = limit <= 0 ? Integer.MAX_VALUE : limit; String input = inputSeq.toString(); @@ -393,14 +405,10 @@ public final class Pattern implements Serializable { Matcher matcher = new Matcher(this, inputSeq); int savedPos = 0; - // Add text preceding each occurrence, if enough space. Only do this for - // non-empty input sequences, because otherwise we'd add the "trailing - // empty string" twice. - if (inputSeq.length() != 0) { - while(matcher.find() && list.size() + 1 < maxLength) { - list.add(input.substring(savedPos, matcher.start())); - savedPos = matcher.end(); - } + // Add text preceding each occurrence, if enough space. + while(matcher.find() && list.size() + 1 < maxLength) { + list.add(input.substring(savedPos, matcher.start())); + savedPos = matcher.end(); } // Add trailing text if enough space. @@ -412,11 +420,10 @@ public final class Pattern implements Serializable { } } - // Remove trailing spaces, if limit == 0 is requested. + // Remove trailing empty matches in the limit == 0 case. if (limit == 0) { int i = list.size() - 1; - // Don't remove 1st element, since array must not be empty. - while(i > 0 && "".equals(list.get(i))) { + while (i >= 0 && "".equals(list.get(i))) { list.remove(i); i--; } diff --git a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java index ea615c0..894dfff 100644 --- a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java +++ b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java @@ -32,12 +32,62 @@ public class SplitTest extends TestCase { Pattern p = Pattern.compile("/"); String[] results = p.split("have/you/done/it/right"); String[] expected = new String[] { "have", "you", "done", "it", "right" }; - assertEquals(expected.length, results.length); + assertArraysEqual(expected, results); + } + + @TestTargets({ + @TestTargetNew( + level = TestLevel.PARTIAL_COMPLETE, + notes = "Verifies the basic functionality of split with empty matches.", + method = "split", + args = {java.lang.CharSequence.class} + ) + }) + public void testEmptySplits() { + // Trailing empty matches are removed. + assertArraysEqual(new String[0], "hello".split(".")); + assertArraysEqual(new String[] { "1", "2" }, "1:2:".split(":")); + // ...including when that results in an empty result. + assertArraysEqual(new String[0], ":".split(":")); + // ...but not when limit < 0. + assertArraysEqual(new String[] { "1", "2", "" }, "1:2:".split(":", -1)); + + // Leading empty matches are retained. + assertArraysEqual(new String[] { "", "", "o" }, "hello".split("..")); + + // A separator that doesn't occur in the input gets you the input. + assertArraysEqual(new String[] { "hello" }, "hello".split("not-present-in-test")); + // ...including when the input is the empty string. + // (Perl returns an empty list instead.) + assertArraysEqual(new String[] { "" }, "".split("not-present-in-test")); + assertArraysEqual(new String[] { "" }, "".split("A?")); + + // The limit argument controls the size of the result. + // If l == 0, the result is as long as needed, except trailing empty matches are dropped. + // If l < 0, the result is as long as needed, and trailing empty matches are retained. + // If l > 0, the result contains the first l matches, plus one string containing the remaining input. + // Examples without a trailing separator (and hence without a trailing empty match): + assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 0)); + assertArraysEqual(new String[] { "a,b,c" }, "a,b,c".split(",", 1)); + assertArraysEqual(new String[] { "a", "b,c" }, "a,b,c".split(",", 2)); + assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", 3)); + assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c".split(",", Integer.MAX_VALUE)); + // Examples with a trailing separator (and hence possibly with a trailing empty match): + assertArraysEqual(new String[] { "a", "b", "c" }, "a,b,c,".split(",", 0)); + assertArraysEqual(new String[] { "a,b,c," }, "a,b,c,".split(",", 1)); + assertArraysEqual(new String[] { "a", "b,c," }, "a,b,c,".split(",", 2)); + assertArraysEqual(new String[] { "a", "b", "c," }, "a,b,c,".split(",", 3)); + assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", Integer.MAX_VALUE)); + assertArraysEqual(new String[] { "a", "b", "c", "" }, "a,b,c,".split(",", -1)); + } + + private void assertArraysEqual(String[] expected, String[] actual) { + assertEquals(expected.length, actual.length); for (int i = 0; i < expected.length; i++) { - assertEquals(results[i], expected[i]); + assertEquals(Integer.toString(i), expected[i], actual[i]); } } - + @TestTargetNew( level = TestLevel.PARTIAL_COMPLETE, notes = "Verifies the functionality of split(java.lang.CharSequence). Test uses not empty pattern.", |