summaryrefslogtreecommitdiffstats
path: root/regex
diff options
context:
space:
mode:
authorAndroid (Google) Code Review <android-gerrit@google.com>2009-09-02 11:53:49 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2009-09-02 11:53:49 -0700
commit7bf214398f31eb5b6b613346a4214bcb59ea2018 (patch)
tree947e5cd01d423106ac539aa4c7d95e93fdd0d707 /regex
parent051128862ae7c5c031b8ddb763848ed264a63746 (diff)
parent51809b9c7995d8b813f68712b096d23179de3af0 (diff)
downloadlibcore-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.java59
-rw-r--r--regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/SplitTest.java56
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
- * &quot;remaining&quot; 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 &gt; 0, it is guaranteed that the resulting array
- * contains at most n entries.
+ * <li>For n &gt; 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 &lt; 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 &lt; 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.",