From 5b83eb9358fea34692be7e712791d19fc64f352a Mon Sep 17 00:00:00 2001
From: Alex Chaffee Remove the last newline, and everything after it from a String. Remove one newline from end of a String if it's there,
+ * otherwise leave it alone. A newline is "\n", "\r", or "\r\n".
+ *
+ * Note that this behavior has changed from 1.0. It
+ * now more closely matches Perl chomp. For the previous behavior,
+ * use slice(String).
*
- * @param str String to chomp the newline from
- * @return String without chomped newline
+ * @param str String to chomp a newline from
+ * @return String without newline
* @throws NullPointerException if str is Remove the last value of a supplied String, and everything after
- * it from a String. Remove one string (the separator) from the end of another
+ * string if it's there, otherwise leave it alone.
+ *
+ *
+ * Note that this behavior has changed from 1.0. It
+ * now more closely matches Perl chomp. For the previous behavior,
+ * use slice(String,String).
+ *
+ * @param str string to chomp from
+ * @param separator separator string
+ * @return String without trailing separator
+ * @throws NullPointerException if str is Remove a newline if and only if it is at the end
* of the supplied String. Remove everything and return the last value of a supplied String, and
- * everything after it from a String.null
*/
public static String chomp(String str) {
- return chomp(str, "\n");
- }
-
- /**
- * null
- */
- public static String chomp(String str, String sep) {
- int idx = str.lastIndexOf(sep);
- if (idx != -1) {
- return str.substring(0, idx);
- } else {
+ if (str.length() == 0) {
return str;
}
+
+ if (str.length() == 1) {
+ if ("\r".equals(str) || "\n".equals(str)) {
+ return "";
+ }
+ else {
+ return str;
+ }
+ }
+
+ int lastIdx = str.length() - 1;
+ char last = str.charAt(lastIdx);
+
+ if (last == '\n') {
+ if (str.charAt(lastIdx - 1) == '\r') {
+ lastIdx--;
+ }
+ } else if (last == '\r') {
+
+ } else {
+ lastIdx++;
+ }
+ return str.substring(0, lastIdx);
}
-
+
+ /**
+ * null
+ */
+ public static String chomp(String str, String separator) {
+ if (str.length() == 0) {
+ return str;
+ }
+ if (str.endsWith(separator)) {
+ return str.substring(0, str.length() - separator.length());
+ }
+ return str;
+ }
+
/**
* null
+ * @deprecated use chomp(String) instead
*/
public static String chompLast(String str) {
return chompLast(str, "\n");
@@ -869,6 +906,7 @@ public class StringUtils {
* @param sep String to chomp
* @return String without chomped ending
* @throws NullPointerException if str or sep is null
+ * @deprecated use chomp(String,String) instead
*/
public static String chompLast(String str, String sep) {
if (str.length() == 0) {
@@ -884,12 +922,14 @@ public class StringUtils {
/**
*
null
+ * @deprecated use sliceRemainder(String,String) instead
*/
public static String getChomp(String str, String sep) {
int idx = str.lastIndexOf(sep);
@@ -910,6 +950,7 @@ public class StringUtils {
* @param sep String to chomp
* @return String without chomped beginning
* @throws NullPointerException if str or sep is null
+ * @deprecated use sliceFirstRemainder(String,String) instead
*/
public static String prechomp(String str, String sep) {
int idx = str.indexOf(sep);
@@ -928,6 +969,7 @@ public class StringUtils {
* @param sep String to chomp
* @return String prechomped
* @throws NullPointerException if str or sep is null
+ * @deprecated use sliceFirst(String) instead
*/
public static String getPrechomp(String str, String sep) {
int idx = str.indexOf(sep);
@@ -976,6 +1018,7 @@ public class StringUtils {
* @param str String to chop a newline from
* @return String without newline
* @throws NullPointerException if str is null
+ * @deprecated use chomp(String) instead
*/
public static String chopNewline(String str) {
int lastIdx = str.length() - 1;
@@ -991,6 +1034,102 @@ public class StringUtils {
}
+ // Slicing
+ //--------------------------------------------------------------------------
+
+ /**
+ * Remove the last newline, and everything after it from a String.
+ * (This method was formerly named chomp or chopNewline.) + * + * @param str String to slice the newline from + * @return String without sliced newline + * @throws NullPointerException if str isnull
+ */
+ public static String slice(String str) {
+ return slice(str, "\n");
+ }
+
+ /**
+ * Find the last occurence of a separator String; + * remove it and everything after it.
+ * (This method was formerly named chomp.) + * + * @param str String to slice from + * @param sep String to slice + * @return String without sliced ending + * @throws NullPointerException if str or sep isnull
+ */
+ public static String slice(String str, String sep) {
+ int idx = str.lastIndexOf(sep);
+ if (idx != -1) {
+ return str.substring(0, idx);
+ } else {
+ return str;
+ }
+ }
+
+ /**
+ * Find the last occurence of a separator String, and return + * everything after it.
+ * (This method was formerly named getchomp. Also, now it does not + * include the separator in the return value.) + * + * @param str String to slice from + * @param sep String to slice + * @return String sliced + * @throws NullPointerException if str or sep isnull
+ */
+ public static String sliceRemainder(String str, String sep) {
+ int idx = str.lastIndexOf(sep);
+ if (idx == str.length() - sep.length()) {
+ return "";
+ } else if (idx != -1) {
+ return str.substring(idx + sep.length());
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Find the first occurence of a separator String, and return + * everything after it.
+ * (This method was formerly named prechomp. Also, previously + * it included the separator in the return value; now it does not.) + * + * @param str String to slice from + * @param sep String to slice + * @return String without sliced beginning + * @throws NullPointerException if str or sep isnull
+ */
+ public static String sliceFirstRemainder(String str, String sep) {
+ int idx = str.indexOf(sep);
+ if (idx != -1) {
+ return str.substring(idx + sep.length());
+ } else {
+ return str;
+ }
+ }
+
+ /**
+ * Find the first occurence of a separator string; + * return everything before it (but not including the separator).
+ * (This method was formerly named getPrechomp. Also, it used to + * include the separator, but now it does not.) + * + * @param str String to slice from + * @param sep String to slice + * @return String presliced + * @throws NullPointerException if str or sep isnull
+ */
+ public static String sliceFirst(String str, String sep) {
+ int idx = str.indexOf(sep);
+ if (idx != -1) {
+ return str.substring(0, idx);
+ } else {
+ return "";
+ }
+ }
+
// Conversion
//--------------------------------------------------------------------------
diff --git a/src/test/org/apache/commons/lang/StringUtilsTest.java b/src/test/org/apache/commons/lang/StringUtilsTest.java
index 3895bed42..01d482c9a 100644
--- a/src/test/org/apache/commons/lang/StringUtilsTest.java
+++ b/src/test/org/apache/commons/lang/StringUtilsTest.java
@@ -69,7 +69,7 @@ import junit.textui.TestRunner;
* @author Henning P. Schmiedehausen
- * @version $Id: StringUtilsTest.java,v 1.16 2003/03/23 21:51:19 scolebourne Exp $
+ * @version $Id: StringUtilsTest.java,v 1.17 2003/03/29 16:17:21 alex Exp $
*/
public class StringUtilsTest extends TestCase {
@@ -153,7 +153,7 @@ public class StringUtilsTest extends TestCase {
}
public void testJoin() {
- assertEquals("concatenate(Object[]) failed",
+ assertEquals("concatenate(Object[]) failed",
TEXT_LIST_NOSEP, StringUtils.concatenate(ARRAY_LIST));
assertEquals("join(Object[], String) failed", TEXT_LIST,
StringUtils.join(ARRAY_LIST, SEPARATOR));
@@ -173,7 +173,7 @@ public class StringUtilsTest extends TestCase {
StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(),
null));
- assertEquals("concatenate(Object[]) failed",
+ assertEquals("concatenate(Object[]) failed",
"", StringUtils.concatenate(EMPTY_ARRAY_LIST));
assertEquals("join(Object[], String) failed", "",
StringUtils.join(EMPTY_ARRAY_LIST, SEPARATOR));
@@ -268,10 +268,7 @@ public class StringUtilsTest extends TestCase {
" "+FOO+" ", StringUtils.center(FOO, 9) );
}
- public void testChompFunctions() {
- assertEquals("chomp(String) failed",
- FOO, StringUtils.chomp(FOO + "\n" + FOO) );
-
+ public void testDeprecatedChompFunctions() {
assertEquals("chompLast(String) failed",
FOO, StringUtils.chompLast(FOO + "\n") );
@@ -284,13 +281,90 @@ public class StringUtilsTest extends TestCase {
assertEquals("getPrechomp(String, String) failed",
FOO + "\n", StringUtils.getPrechomp(FOO + "\n" + FOO, "\n") );
- assertEquals("chop(String, String) failed",
- FOO, StringUtils.chop(FOO + "\r\n") );
-
assertEquals("chopNewline(String, String) failed",
FOO, StringUtils.chopNewline(FOO + "\r\n") );
}
+ public void testChop() {
+
+ String[][] chopCases = {
+ { FOO + "\r\n", FOO } ,
+ { FOO + "\n" , FOO } ,
+ { FOO + "\r", FOO },
+ { "foo", "fo"},
+ { "foo\nfoo", "foo\nfo" },
+ { "\n", "" },
+ { "\r", "" },
+ { "\r\n", "" },
+ };
+ for (int i = 0; i < chopCases.length; i++) {
+ String original = chopCases[i][0];
+ String expectedResult = chopCases[i][1];
+ assertEquals("chop(String) failed",
+ expectedResult, StringUtils.chop(original));
+ }
+ }
+
+ public void testChomp() {
+
+ String[][] chompCases = {
+ { FOO + "\r\n", FOO } ,
+ { FOO + "\n" , FOO } ,
+ { FOO + "\r", FOO },
+ { FOO, FOO },
+ { FOO + "\n\n", FOO + "\n"},
+ { "foo\nfoo", "foo\nfoo" },
+ { "\n", "" },
+ { "\r", "" },
+ { "\r\n", "" },
+ };
+ for (int i = 0; i < chompCases.length; i++) {
+ String original = chompCases[i][0];
+ String expectedResult = chompCases[i][1];
+ assertEquals("chomp(String) failed",
+ expectedResult, StringUtils.chomp(original));
+ }
+
+ assertEquals("chomp(String, String) failed",
+ "foo", StringUtils.chomp("foobar", "bar"));
+ assertEquals("chomp(String, String) failed",
+ "foobar", StringUtils.chomp("foobar", "baz"));
+ assertEquals("chomp(String, String) failed",
+ "foo", StringUtils.chomp("foo", "foooo"));
+ }
+
+ public void testSliceFunctions() {
+
+ String[][] sliceCases = {
+ {"foo\n", "foo"},
+ {"foo\nbar", "foo"},
+ {"foo\nbar\n", "foo\nbar"},
+ {"foo\nbar\nbaz", "foo\nbar"},
+ };
+ for (int i = 0; i < sliceCases.length; i++) {
+ String original = sliceCases[i][0];
+ String expectedResult = sliceCases[i][1];
+ assertEquals("slice(String) failed",
+ expectedResult, StringUtils.slice(original));
+ }
+
+ String original = "fooXXbarXXbaz";
+ String sep = "XX";
+
+ assertEquals("slice(String,String) failed",
+ "fooXXbar", StringUtils.slice(original, sep) );
+
+ assertEquals("sliceRemainder(String, String) failed",
+ "baz", StringUtils.sliceRemainder(original, sep) );
+
+ assertEquals("sliceFirst(String, String) failed",
+ "foo", StringUtils.sliceFirst(original, sep) );
+
+ assertEquals("sliceFirstRemainder(String, String) failed",
+ "barXXbaz", StringUtils.sliceFirstRemainder(original, sep) );
+
+ }
+
public void testPadFunctions() {
assertEquals("rightPad(String, int) failed",
"1234 ", StringUtils.rightPad ("1234", 8) );
@@ -317,13 +391,13 @@ public class StringUtilsTest extends TestCase {
assertEquals("reverse(empty-string) failed",
"", StringUtils.reverse("") );
assertEquals("reverseDelimitedString(String,'.') failed",
- "org.apache.test",
+ "org.apache.test",
StringUtils.reverseDelimitedString("test.apache.org", ".") );
assertEquals("reverseDelimitedString(empty-string,'.') failed",
- "",
+ "",
StringUtils.reverseDelimitedString("", ".") );
assertEquals("reverseDelimitedString(String,' ') failed",
- "once upon a time",
+ "once upon a time",
StringUtils.reverseDelimitedString("time a upon once"," ") );
}
@@ -359,13 +433,13 @@ public class StringUtilsTest extends TestCase {
"\\u0234", StringUtils.escape("\u0234") );
assertEquals("escape(String) failed",
"\\u00fd", StringUtils.escape("\u00fd") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"", StringUtils.unescape("") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"test", StringUtils.unescape("test") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"\ntest\b", StringUtils.unescape("\\ntest\\b") );
- assertEquals("unescape(String) failed",
+ assertEquals("unescape(String) failed",
"\u123425foo\ntest\b", StringUtils.unescape("\\u123425foo\\ntest\\b") );
}