changed chomp() to match Perl

deprecated chomp* methods in favor of new slice methods
improved unit tests and documentation


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137277 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Alex Chaffee 2003-03-29 16:17:21 +00:00
parent edb0e8d284
commit 5b83eb9358
2 changed files with 255 additions and 42 deletions

View File

@ -78,7 +78,7 @@ import org.apache.commons.lang.exception.NestableRuntimeException;
* @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
* @author Arun Mammen Thomas * @author Arun Mammen Thomas
* @since 1.0 * @since 1.0
* @version $Id: StringUtils.java,v 1.39 2003/03/25 00:15:58 scolebourne Exp $ * @version $Id: StringUtils.java,v 1.40 2003/03/29 16:17:21 alex Exp $
*/ */
public class StringUtils { public class StringUtils {
@ -820,36 +820,72 @@ public class StringUtils {
// Chomping // Chomping
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/** /**
* <p>Remove the last newline, and everything after it from a String.</p> * <p>Remove one newline from end of a String if it's there,
* otherwise leave it alone. A newline is "\n", "\r", or "\r\n".
* <p>
* 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 * @param str String to chomp a newline from
* @return String without chomped newline * @return String without newline
* @throws NullPointerException if str is <code>null</code> * @throws NullPointerException if str is <code>null</code>
*/ */
public static String chomp(String str) { public static String chomp(String str) {
return chomp(str, "\n"); if (str.length() == 0) {
}
/**
* <p>Remove the last value of a supplied String, and everything after
* it from a String.</p>
*
* @param str String to chomp from
* @param sep String to chomp
* @return String without chomped ending
* @throws NullPointerException if str or sep is <code>null</code>
*/
public static String chomp(String str, String sep) {
int idx = str.lastIndexOf(sep);
if (idx != -1) {
return str.substring(0, idx);
} else {
return str; 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);
} }
/**
* <p>Remove one string (the separator) from the end of another
* string if it's there, otherwise leave it alone.
* <p>
*
* 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 <code>null</code>
*/
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;
}
/** /**
* <p>Remove a newline if and only if it is at the end * <p>Remove a newline if and only if it is at the end
* of the supplied String.</p> * of the supplied String.</p>
@ -857,6 +893,7 @@ public class StringUtils {
* @param str String to chomp from * @param str String to chomp from
* @return String without chomped ending * @return String without chomped ending
* @throws NullPointerException if str is <code>null</code> * @throws NullPointerException if str is <code>null</code>
* @deprecated use chomp(String) instead
*/ */
public static String chompLast(String str) { public static String chompLast(String str) {
return chompLast(str, "\n"); return chompLast(str, "\n");
@ -869,6 +906,7 @@ public class StringUtils {
* @param sep String to chomp * @param sep String to chomp
* @return String without chomped ending * @return String without chomped ending
* @throws NullPointerException if str or sep is <code>null</code> * @throws NullPointerException if str or sep is <code>null</code>
* @deprecated use chomp(String,String) instead
*/ */
public static String chompLast(String str, String sep) { public static String chompLast(String str, String sep) {
if (str.length() == 0) { if (str.length() == 0) {
@ -884,12 +922,14 @@ public class StringUtils {
/** /**
* <p>Remove everything and return the last value of a supplied String, and * <p>Remove everything and return the last value of a supplied String, and
* everything after it from a String.</p> * everything after it from a String.
* [That makes no sense. Just use sliceRemainder() :-)]</p>
* *
* @param str String to chomp from * @param str String to chomp from
* @param sep String to chomp * @param sep String to chomp
* @return String chomped * @return String chomped
* @throws NullPointerException if str or sep is <code>null</code> * @throws NullPointerException if str or sep is <code>null</code>
* @deprecated use sliceRemainder(String,String) instead
*/ */
public static String getChomp(String str, String sep) { public static String getChomp(String str, String sep) {
int idx = str.lastIndexOf(sep); int idx = str.lastIndexOf(sep);
@ -910,6 +950,7 @@ public class StringUtils {
* @param sep String to chomp * @param sep String to chomp
* @return String without chomped beginning * @return String without chomped beginning
* @throws NullPointerException if str or sep is <code>null</code> * @throws NullPointerException if str or sep is <code>null</code>
* @deprecated use sliceFirstRemainder(String,String) instead
*/ */
public static String prechomp(String str, String sep) { public static String prechomp(String str, String sep) {
int idx = str.indexOf(sep); int idx = str.indexOf(sep);
@ -928,6 +969,7 @@ public class StringUtils {
* @param sep String to chomp * @param sep String to chomp
* @return String prechomped * @return String prechomped
* @throws NullPointerException if str or sep is <code>null</code> * @throws NullPointerException if str or sep is <code>null</code>
* @deprecated use sliceFirst(String) instead
*/ */
public static String getPrechomp(String str, String sep) { public static String getPrechomp(String str, String sep) {
int idx = str.indexOf(sep); int idx = str.indexOf(sep);
@ -976,6 +1018,7 @@ public class StringUtils {
* @param str String to chop a newline from * @param str String to chop a newline from
* @return String without newline * @return String without newline
* @throws NullPointerException if str is <code>null</code> * @throws NullPointerException if str is <code>null</code>
* @deprecated use chomp(String) instead
*/ */
public static String chopNewline(String str) { public static String chopNewline(String str) {
int lastIdx = str.length() - 1; int lastIdx = str.length() - 1;
@ -991,6 +1034,102 @@ public class StringUtils {
} }
// Slicing
//--------------------------------------------------------------------------
/**
* <p>Remove the last newline, and everything after it from a String.</p>
* (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 is <code>null</code>
*/
public static String slice(String str) {
return slice(str, "\n");
}
/**
* <p>Find the last occurence of a separator String;
* remove it and everything after it.</p>
* (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 is <code>null</code>
*/
public static String slice(String str, String sep) {
int idx = str.lastIndexOf(sep);
if (idx != -1) {
return str.substring(0, idx);
} else {
return str;
}
}
/**
* <p>Find the last occurence of a separator String, and return
* everything after it.</p>
* (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 is <code>null</code>
*/
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 "";
}
}
/**
* <p>Find the first occurence of a separator String, and return
* everything after it.</p>
* (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 is <code>null</code>
*/
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;
}
}
/**
* <p>Find the first occurence of a separator string;
* return everything before it (but not including the separator).</p>
* (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 is <code>null</code>
*/
public static String sliceFirst(String str, String sep) {
int idx = str.indexOf(sep);
if (idx != -1) {
return str.substring(0, idx);
} else {
return "";
}
}
// Conversion // Conversion
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View File

@ -69,7 +69,7 @@ import junit.textui.TestRunner;
* @author <a href="mailto:fredrik@westermarck.com>Fredrik Westermarck</a> * @author <a href="mailto:fredrik@westermarck.com>Fredrik Westermarck</a>
* @author Holger Krauth * @author Holger Krauth
* @author <a href="hps@intermeta.de">Henning P. Schmiedehausen</a> * @author <a href="hps@intermeta.de">Henning P. Schmiedehausen</a>
* @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 { public class StringUtilsTest extends TestCase {
@ -153,7 +153,7 @@ public class StringUtilsTest extends TestCase {
} }
public void testJoin() { public void testJoin() {
assertEquals("concatenate(Object[]) failed", assertEquals("concatenate(Object[]) failed",
TEXT_LIST_NOSEP, StringUtils.concatenate(ARRAY_LIST)); TEXT_LIST_NOSEP, StringUtils.concatenate(ARRAY_LIST));
assertEquals("join(Object[], String) failed", TEXT_LIST, assertEquals("join(Object[], String) failed", TEXT_LIST,
StringUtils.join(ARRAY_LIST, SEPARATOR)); StringUtils.join(ARRAY_LIST, SEPARATOR));
@ -173,7 +173,7 @@ public class StringUtilsTest extends TestCase {
StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(), StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(),
null)); null));
assertEquals("concatenate(Object[]) failed", assertEquals("concatenate(Object[]) failed",
"", StringUtils.concatenate(EMPTY_ARRAY_LIST)); "", StringUtils.concatenate(EMPTY_ARRAY_LIST));
assertEquals("join(Object[], String) failed", "", assertEquals("join(Object[], String) failed", "",
StringUtils.join(EMPTY_ARRAY_LIST, SEPARATOR)); StringUtils.join(EMPTY_ARRAY_LIST, SEPARATOR));
@ -268,10 +268,7 @@ public class StringUtilsTest extends TestCase {
" "+FOO+" ", StringUtils.center(FOO, 9) ); " "+FOO+" ", StringUtils.center(FOO, 9) );
} }
public void testChompFunctions() { public void testDeprecatedChompFunctions() {
assertEquals("chomp(String) failed",
FOO, StringUtils.chomp(FOO + "\n" + FOO) );
assertEquals("chompLast(String) failed", assertEquals("chompLast(String) failed",
FOO, StringUtils.chompLast(FOO + "\n") ); FOO, StringUtils.chompLast(FOO + "\n") );
@ -284,13 +281,90 @@ public class StringUtilsTest extends TestCase {
assertEquals("getPrechomp(String, String) failed", assertEquals("getPrechomp(String, String) failed",
FOO + "\n", StringUtils.getPrechomp(FOO + "\n" + FOO, "\n") ); FOO + "\n", StringUtils.getPrechomp(FOO + "\n" + FOO, "\n") );
assertEquals("chop(String, String) failed",
FOO, StringUtils.chop(FOO + "\r\n") );
assertEquals("chopNewline(String, String) failed", assertEquals("chopNewline(String, String) failed",
FOO, StringUtils.chopNewline(FOO + "\r\n") ); 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() { public void testPadFunctions() {
assertEquals("rightPad(String, int) failed", assertEquals("rightPad(String, int) failed",
"1234 ", StringUtils.rightPad ("1234", 8) ); "1234 ", StringUtils.rightPad ("1234", 8) );
@ -317,13 +391,13 @@ public class StringUtilsTest extends TestCase {
assertEquals("reverse(empty-string) failed", assertEquals("reverse(empty-string) failed",
"", StringUtils.reverse("") ); "", StringUtils.reverse("") );
assertEquals("reverseDelimitedString(String,'.') failed", assertEquals("reverseDelimitedString(String,'.') failed",
"org.apache.test", "org.apache.test",
StringUtils.reverseDelimitedString("test.apache.org", ".") ); StringUtils.reverseDelimitedString("test.apache.org", ".") );
assertEquals("reverseDelimitedString(empty-string,'.') failed", assertEquals("reverseDelimitedString(empty-string,'.') failed",
"", "",
StringUtils.reverseDelimitedString("", ".") ); StringUtils.reverseDelimitedString("", ".") );
assertEquals("reverseDelimitedString(String,' ') failed", assertEquals("reverseDelimitedString(String,' ') failed",
"once upon a time", "once upon a time",
StringUtils.reverseDelimitedString("time a upon once"," ") ); StringUtils.reverseDelimitedString("time a upon once"," ") );
} }
@ -359,13 +433,13 @@ public class StringUtilsTest extends TestCase {
"\\u0234", StringUtils.escape("\u0234") ); "\\u0234", StringUtils.escape("\u0234") );
assertEquals("escape(String) failed", assertEquals("escape(String) failed",
"\\u00fd", StringUtils.escape("\u00fd") ); "\\u00fd", StringUtils.escape("\u00fd") );
assertEquals("unescape(String) failed", assertEquals("unescape(String) failed",
"", StringUtils.unescape("") ); "", StringUtils.unescape("") );
assertEquals("unescape(String) failed", assertEquals("unescape(String) failed",
"test", StringUtils.unescape("test") ); "test", StringUtils.unescape("test") );
assertEquals("unescape(String) failed", assertEquals("unescape(String) failed",
"\ntest\b", StringUtils.unescape("\\ntest\\b") ); "\ntest\b", StringUtils.unescape("\\ntest\\b") );
assertEquals("unescape(String) failed", assertEquals("unescape(String) failed",
"\u123425foo\ntest\b", StringUtils.unescape("\\u123425foo\\ntest\\b") ); "\u123425foo\ntest\b", StringUtils.unescape("\\u123425foo\\ntest\\b") );
} }