Add StrMatcher and update StrBuilder and test cases to use it, plus fix other bugs
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@232652 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
512574a908
commit
810e69f7a4
|
@ -242,6 +242,8 @@ public void clear() {
|
|||
/**
|
||||
* Gets the character at the specified index.
|
||||
*
|
||||
* @see #setCharAt(int, char)
|
||||
* @see #deleteCharAt(int)
|
||||
* @param index the index to retrieve, must be valid
|
||||
* @return the character at the index
|
||||
* @throws IndexOutOfBoundsException if the index is invalid
|
||||
|
@ -256,6 +258,8 @@ public char charAt(int index) {
|
|||
/**
|
||||
* Sets the character at the specified index.
|
||||
*
|
||||
* @see #charAt(int)
|
||||
* @see #deleteCharAt(int)
|
||||
* @param index the index to set
|
||||
* @param ch the new character
|
||||
* @throws IndexOutOfBoundsException if the index is invalid
|
||||
|
@ -267,6 +271,23 @@ public void setCharAt(int index, char ch) {
|
|||
buffer[index] = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the character at the specified index.
|
||||
*
|
||||
* @see #charAt(int)
|
||||
* @see #setCharAt(int, char)
|
||||
* @param index the index to delete
|
||||
* @return this, to enable chaining
|
||||
* @throws IndexOutOfBoundsException if the index is invalid
|
||||
*/
|
||||
public StrBuilder deleteCharAt(int index) {
|
||||
if (index < 0 || index >= size) {
|
||||
throw new StringIndexOutOfBoundsException(index);
|
||||
}
|
||||
deleteImpl(index, index + 1, 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Copies the builder's character array into a new character array.
|
||||
|
@ -1024,6 +1045,19 @@ public StrBuilder insert(int index, double value) {
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Internal method to delete a range without validation.
|
||||
*
|
||||
* @param startIndex the start index, must be valid
|
||||
* @param endIndex the end index (exclusive), must be valid
|
||||
* @param len the length, must be valid
|
||||
* @throws IndexOutOfBoundsException if any index is invalid
|
||||
*/
|
||||
private void deleteImpl(int startIndex, int endIndex, int len) {
|
||||
System.arraycopy(buffer, endIndex, buffer, startIndex, size - endIndex);
|
||||
size -= len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the characters between the two specified indices.
|
||||
*
|
||||
|
@ -1037,35 +1071,19 @@ public StrBuilder delete(int startIndex, int endIndex) {
|
|||
endIndex = validateRange(startIndex, endIndex);
|
||||
int len = endIndex - startIndex;
|
||||
if (len > 0) {
|
||||
System.arraycopy(buffer, endIndex, buffer, startIndex, size - endIndex);
|
||||
size -= len;
|
||||
deleteImpl(startIndex, endIndex, len);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the character at the specified index.
|
||||
*
|
||||
* @param index the index to delete
|
||||
* @return this, to enable chaining
|
||||
* @throws IndexOutOfBoundsException if the index is invalid
|
||||
*/
|
||||
public StrBuilder deleteCharAt(int index) {
|
||||
if (index < 0 || index >= size) {
|
||||
throw new StringIndexOutOfBoundsException(index);
|
||||
}
|
||||
System.arraycopy(buffer, index + 1, buffer, index, size - index - 1);
|
||||
size--;
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Deletes the character wherever it occurs in the builder.
|
||||
*
|
||||
*
|
||||
* @param ch the character to delete
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder delete(char ch) {
|
||||
public StrBuilder deleteAll(char ch) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (buffer[i] == ch) {
|
||||
int start = i;
|
||||
|
@ -1074,26 +1092,25 @@ public StrBuilder delete(char ch) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
System.arraycopy(buffer, i, buffer, start, size - i);
|
||||
size -= (i - start);
|
||||
int len = i - start;
|
||||
deleteImpl(start, i, len);
|
||||
i -= len;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the string wherever it occurs in the builder.
|
||||
*
|
||||
* @param str the string to delete, null causes no action
|
||||
* Deletes the character wherever it occurs in the builder.
|
||||
*
|
||||
* @param ch the character to delete
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder delete(String str) {
|
||||
int len = (str == null ? 0 : str.length());
|
||||
if (len > 0) {
|
||||
int index = indexOf(str, 0);
|
||||
while (index >= 0) {
|
||||
delete(index, index + len);
|
||||
index = indexOf(str, index);
|
||||
public StrBuilder deleteFirst(char ch) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (buffer[i] == ch) {
|
||||
deleteImpl(i, i + 1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
@ -1101,68 +1118,121 @@ public StrBuilder delete(String str) {
|
|||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Replaces a portion of the string builder with another string.
|
||||
* The length of the inserted string does not have to match the removed length.
|
||||
*
|
||||
* @param startIndex the start index, inclusive, must be valid
|
||||
* @param endIndex the end index, exclusive, must be valid except
|
||||
* that if too large it is treated as end of string
|
||||
* @param str the string to replace with
|
||||
* Deletes the string wherever it occurs in the builder.
|
||||
*
|
||||
* @param str the string to delete, null causes no action
|
||||
* @return this, to enable chaining
|
||||
* @throws IndexOutOfBoundsException if the index is invalid
|
||||
*/
|
||||
public StrBuilder replace(int startIndex, int endIndex, String str) {
|
||||
endIndex = validateRange(startIndex, endIndex);
|
||||
int insertLen = str.length();
|
||||
int removeLen = endIndex - startIndex;
|
||||
int newSize = size - removeLen + insertLen;
|
||||
if (insertLen > removeLen) {
|
||||
ensureCapacity(newSize);
|
||||
public StrBuilder deleteAll(String str) {
|
||||
int len = (str == null ? 0 : str.length());
|
||||
if (len > 0) {
|
||||
int index = indexOf(str, 0);
|
||||
while (index >= 0) {
|
||||
deleteImpl(index, index + len, len);
|
||||
index = indexOf(str, index);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the string wherever it occurs in the builder.
|
||||
*
|
||||
* @param str the string to delete, null causes no action
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder deleteFirst(String str) {
|
||||
int len = (str == null ? 0 : str.length());
|
||||
if (len > 0) {
|
||||
int index = indexOf(str, 0);
|
||||
if (index >= 0) {
|
||||
deleteImpl(index, index + len, len);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Deletes all parts of the builder that the matcher matches.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced deletion behaviour.
|
||||
* For example you could write a matcher to delete all occurances
|
||||
* where the character 'a' is followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use to find the deletion, null causes no action
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder deleteAll(StrMatcher matcher) {
|
||||
return replace(matcher, null, 0, size, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the first match within the builder using the specified matcher.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced deletion behaviour.
|
||||
* For example you could write a matcher to delete
|
||||
* where the character 'a' is followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use to find the deletion, null causes no action
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder deleteFirst(StrMatcher matcher) {
|
||||
return replace(matcher, null, 0, size, 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Internal method to delete a range without validation.
|
||||
*
|
||||
* @param startIndex the start index, must be valid
|
||||
* @param endIndex the end index (exclusive), must be valid
|
||||
* @param removeLen the length to remove (endIndex - startIndex), must be valid
|
||||
* @param insertStr the string to replace with, null means delete range
|
||||
* @param insertLen the length of the insert string, must be valid
|
||||
* @param len the length, must be valid
|
||||
* @throws IndexOutOfBoundsException if any index is invalid
|
||||
*/
|
||||
private void replaceImpl(int startIndex, int endIndex, int removeLen, String insertStr, int insertLen) {
|
||||
int newSize = size - removeLen + insertLen;
|
||||
if (insertLen != removeLen) {
|
||||
ensureCapacity(newSize);
|
||||
System.arraycopy(buffer, endIndex, buffer, startIndex + insertLen, size - endIndex);
|
||||
size = newSize;
|
||||
}
|
||||
str.getChars(0, insertLen, buffer, startIndex);
|
||||
return this;
|
||||
if (insertLen > 0) {
|
||||
insertStr.getChars(0, insertLen, buffer, startIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a portion of the string builder with another string builder.
|
||||
* Replaces a portion of the string builder with another string.
|
||||
* The length of the inserted string does not have to match the removed length.
|
||||
*
|
||||
*
|
||||
* @param startIndex the start index, inclusive, must be valid
|
||||
* @param endIndex the end index, exclusive, must be valid except
|
||||
* that if too large it is treated as end of string
|
||||
* @param builder the string builder to replace with
|
||||
* @param replaceStr the string to replace with, null means delete range
|
||||
* @return this, to enable chaining
|
||||
* @throws IndexOutOfBoundsException if the index is invalid
|
||||
*/
|
||||
public StrBuilder replace(int startIndex, int endIndex, StrBuilder builder) {
|
||||
public StrBuilder replace(int startIndex, int endIndex, String replaceStr) {
|
||||
endIndex = validateRange(startIndex, endIndex);
|
||||
int insertLen = builder.length();
|
||||
int removeLen = endIndex - startIndex;
|
||||
if (insertLen > removeLen) {
|
||||
ensureCapacity(size - removeLen + insertLen);
|
||||
}
|
||||
if (insertLen != removeLen) {
|
||||
//shift the current characters to the right
|
||||
System.arraycopy(buffer, endIndex, buffer, startIndex + insertLen, size - endIndex);
|
||||
//adjust the size accordingly
|
||||
size += (insertLen - removeLen);
|
||||
}
|
||||
builder.getChars(0, insertLen, buffer, startIndex);
|
||||
int insertLen = (replaceStr == null ? 0 : replaceStr.length());
|
||||
replaceImpl(startIndex, endIndex, endIndex - startIndex, replaceStr, insertLen);
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Replaces the search character with the replace character throughout the builder.
|
||||
*
|
||||
* @param search the search string, null causes no action to occur
|
||||
* @param replace the replace string, null is equivalent to an empty string
|
||||
* Replaces the search character with the replace character
|
||||
* throughout the builder.
|
||||
*
|
||||
* @param search the search character
|
||||
* @param replace the replace character
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder replace(char search, char replace) {
|
||||
public StrBuilder replaceAll(char search, char replace) {
|
||||
if (search != replace) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (buffer[i] == search) {
|
||||
|
@ -1173,21 +1243,153 @@ public StrBuilder replace(char search, char replace) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the first instance of the search character with the
|
||||
* replace character in the builder.
|
||||
*
|
||||
* @param search the search character
|
||||
* @param replace the replace character
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder replaceFirst(char search, char replace) {
|
||||
if (search != replace) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (buffer[i] == search) {
|
||||
buffer[i] = replace;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Replaces the search string with the replace string throughout the builder.
|
||||
*
|
||||
*
|
||||
* @param searchStr the search string, null causes no action to occur
|
||||
* @param replaceStr the replace string, null is equivalent to an empty string
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder replace(String searchStr, String replaceStr) {
|
||||
public StrBuilder replaceAll(String searchStr, String replaceStr) {
|
||||
int searchLen = (searchStr == null ? 0 : searchStr.length());
|
||||
if (searchLen > 0) {
|
||||
replaceStr = (replaceStr == null ? "" : replaceStr);
|
||||
int replaceLen = (replaceStr == null ? 0 : replaceStr.length());
|
||||
int index = indexOf(searchStr, 0);
|
||||
while (index >= 0) {
|
||||
replace(index, index + searchLen, replaceStr);
|
||||
index = indexOf(searchStr, index);
|
||||
replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
|
||||
index = indexOf(searchStr, index + replaceLen);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the first instance of the search string with the replace string.
|
||||
*
|
||||
* @param searchStr the search string, null causes no action to occur
|
||||
* @param replaceStr the replace string, null is equivalent to an empty string
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder replaceFirst(String searchStr, String replaceStr) {
|
||||
int searchLen = (searchStr == null ? 0 : searchStr.length());
|
||||
if (searchLen > 0) {
|
||||
int index = indexOf(searchStr, 0);
|
||||
if (index >= 0) {
|
||||
int replaceLen = (replaceStr == null ? 0 : replaceStr.length());
|
||||
replaceImpl(index, index + searchLen, searchLen, replaceStr, replaceLen);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Replaces all matches within the builder with the replace string.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced replace behaviour.
|
||||
* For example you could write a matcher to replace all occurances
|
||||
* where the character 'a' is followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use to find the deletion, null causes no action
|
||||
* @param replaceStr the replace string, null is equivalent to an empty string
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder replaceAll(StrMatcher matcher, String replaceStr) {
|
||||
return replace(matcher, replaceStr, 0, size, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the first match within the builder with the replace string.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced replace behaviour.
|
||||
* For example you could write a matcher to replace
|
||||
* where the character 'a' is followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use to find the deletion, null causes no action
|
||||
* @param replaceStr the replace string, null is equivalent to an empty string
|
||||
* @return this, to enable chaining
|
||||
*/
|
||||
public StrBuilder replaceFirst(StrMatcher matcher, String replaceStr) {
|
||||
return replace(matcher, replaceStr, 0, size, 1);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
/**
|
||||
* Advanced search and replaces within the builder using a matcher.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced behaviour.
|
||||
* For example you could write a matcher to delete all occurances
|
||||
* where the character 'a' is followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use to find the deletion, null causes no action
|
||||
* @param replaceStr the string to replace the match with, null is a delete
|
||||
* @param startIndex the start index, inclusive, must be valid
|
||||
* @param endIndex the end index, exclusive, must be valid except
|
||||
* that if too large it is treated as end of string
|
||||
* @param replaceCount the number of times to replace, -1 for replace all
|
||||
* @return this, to enable chaining
|
||||
* @throws IndexOutOfBoundsException if start index is invalid
|
||||
*/
|
||||
public StrBuilder replace(
|
||||
StrMatcher matcher, String replaceStr,
|
||||
int startIndex, int endIndex, int replaceCount) {
|
||||
endIndex = validateRange(startIndex, endIndex);
|
||||
return replaceImpl(matcher, replaceStr, startIndex, endIndex, replaceCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces within the builder using a matcher.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced behaviour.
|
||||
* For example you could write a matcher to delete all occurances
|
||||
* where the character 'a' is followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use to find the deletion, null causes no action
|
||||
* @param replaceStr the string to replace the match with, null is a delete
|
||||
* @param from the start index, must be valid
|
||||
* @param to the end index (exclusive), must be valid
|
||||
* @param replaceCount the number of times to replace, -1 for replace all
|
||||
* @return this, to enable chaining
|
||||
* @throws IndexOutOfBoundsException if any index is invalid
|
||||
*/
|
||||
private StrBuilder replaceImpl(
|
||||
StrMatcher matcher, String replaceStr,
|
||||
int from, int to, int replaceCount) {
|
||||
if (matcher == null || size == 0) {
|
||||
return this;
|
||||
}
|
||||
int replaceLen = (replaceStr == null ? 0 : replaceStr.length());
|
||||
char[] buf = buffer;
|
||||
for (int i = from; i < to && replaceCount != 0; i++) {
|
||||
int removeLen = matcher.isMatch(buf, i, from, to);
|
||||
if (removeLen > 0) {
|
||||
replaceImpl(i, i + removeLen, removeLen, replaceStr, replaceLen);
|
||||
to = to - removeLen + replaceLen;
|
||||
i = i + replaceLen - 1;
|
||||
if (replaceCount > 0) {
|
||||
replaceCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
@ -1375,8 +1577,8 @@ public String midString(int index, int length) {
|
|||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Checks of the string builder contains the specified char.
|
||||
*
|
||||
* Checks if the string builder contains the specified char.
|
||||
*
|
||||
* @param ch the character to find
|
||||
* @return true if the builder contains the character
|
||||
*/
|
||||
|
@ -1391,8 +1593,8 @@ public boolean contains(char ch) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks of the string builder contains the specified string.
|
||||
*
|
||||
* Checks if the string builder contains the specified string.
|
||||
*
|
||||
* @param str the string to find
|
||||
* @return true if the builder contains the string
|
||||
*/
|
||||
|
@ -1400,6 +1602,21 @@ public boolean contains(String str) {
|
|||
return indexOf(str, 0) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the string builder contains a string matched using the
|
||||
* specified matcher.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced searching behaviour.
|
||||
* For example you could write a matcher to search for the character
|
||||
* 'a' followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use, null returns -1
|
||||
* @return true if the matcher finds a match in the builder
|
||||
*/
|
||||
public boolean contains(StrMatcher matcher) {
|
||||
return indexOf(matcher, 0) >= 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Searches the string builder to find the first reference to the specified char.
|
||||
|
@ -1415,7 +1632,7 @@ public int indexOf(char ch) {
|
|||
* Searches the string builder to find the first reference to the specified char.
|
||||
*
|
||||
* @param ch the character to find
|
||||
* @param startIndex the index to start at, must be valid
|
||||
* @param startIndex the index to start at, invalid index rounded to edge
|
||||
* @return the first index of the character, or -1 if not found
|
||||
*/
|
||||
public int indexOf(char ch, int startIndex) {
|
||||
|
@ -1451,7 +1668,7 @@ public int indexOf(String str) {
|
|||
* Note that a null input string will return -1, whereas the JDK throws an exception.
|
||||
*
|
||||
* @param str the string to find, null returns -1
|
||||
* @param startIndex the index to start at, must be valid
|
||||
* @param startIndex the index to start at, invalid index rounded to edge
|
||||
* @return the first index of the string, or -1 if not found
|
||||
*/
|
||||
public int indexOf(String str, int startIndex) {
|
||||
|
@ -1481,6 +1698,49 @@ public int indexOf(String str, int startIndex) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the string builder using the matcher to find the first match.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced searching behaviour.
|
||||
* For example you could write a matcher to find the character 'a'
|
||||
* followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use, null returns -1
|
||||
* @return the first index matched, or -1 if not found
|
||||
*/
|
||||
public int indexOf(StrMatcher matcher) {
|
||||
return indexOf(matcher, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the string builder using the matcher to find the first
|
||||
* match searching from the given index.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced searching behaviour.
|
||||
* For example you could write a matcher to find the character 'a'
|
||||
* followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use, null returns -1
|
||||
* @param startIndex the index to start at, invalid index rounded to edge
|
||||
* @return the first index matched, or -1 if not found
|
||||
*/
|
||||
public int indexOf(StrMatcher matcher, int startIndex) {
|
||||
startIndex = (startIndex < 0 ? 0 : startIndex);
|
||||
if (matcher == null || startIndex >= size) {
|
||||
return -1;
|
||||
}
|
||||
int len = size;
|
||||
if (len > 0) {
|
||||
char[] buf = buffer;
|
||||
for (int i = startIndex; i < len; i++) {
|
||||
if (matcher.isMatch(buf, i, startIndex, len) > 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Searches the string builder to find the last reference to the specified char.
|
||||
|
@ -1561,6 +1821,50 @@ public int lastIndexOf(String str, int startIndex) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the string builder using the matcher to find the last match.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced searching behaviour.
|
||||
* For example you could write a matcher to find the character 'a'
|
||||
* followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use, null returns -1
|
||||
* @return the last index matched, or -1 if not found
|
||||
*/
|
||||
public int lastIndexOf(StrMatcher matcher) {
|
||||
return lastIndexOf(matcher, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the string builder using the matcher to find the last
|
||||
* match searching from the given index.
|
||||
* <p>
|
||||
* Matchers can be used to perform advanced searching behaviour.
|
||||
* For example you could write a matcher to find the character 'a'
|
||||
* followed by a number.
|
||||
*
|
||||
* @param matcher the matcher to use, null returns -1
|
||||
* @param startIndex the index to start at, invalid index rounded to edge
|
||||
* @return the last index matched, or -1 if not found
|
||||
*/
|
||||
public int lastIndexOf(StrMatcher matcher, int startIndex) {
|
||||
startIndex = (startIndex >= size ? size - 1 : startIndex);
|
||||
if (matcher == null || startIndex < 0) {
|
||||
return -1;
|
||||
}
|
||||
int len = size;
|
||||
if (len > 0) {
|
||||
char[] buf = buffer;
|
||||
int endIndex = startIndex + 1;
|
||||
for (int i = startIndex; i >= 0; i--) {
|
||||
if (matcher.isMatch(buf, i, 0, endIndex) > 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Gets the contents of this builder as a Reader.
|
||||
|
|
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
* Copyright 2003-2005 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.lang.text;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A matcher class that can be queried to determine if a character array
|
||||
* portion matches.
|
||||
* <p>
|
||||
* This class comes complete with various constants and factory methods.
|
||||
* If these do not suffice, you can subclass and implement your own matcher.
|
||||
*
|
||||
* @author Stephen Colebourne
|
||||
* @since 2.2
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class StrMatcher {
|
||||
|
||||
/**
|
||||
* Matches the comma character.
|
||||
*/
|
||||
private static final StrMatcher COMMA_MATCHER = new CharMatcher(',');
|
||||
/**
|
||||
* Matches the tab character.
|
||||
*/
|
||||
private static final StrMatcher TAB_MATCHER = new CharMatcher('\t');
|
||||
/**
|
||||
* Matches the space character.
|
||||
*/
|
||||
private static final StrMatcher SPACE_MATCHER = new CharMatcher(' ');
|
||||
/**
|
||||
* Matches the same characters as StringTokenizer,
|
||||
* namely space, tab, newline, formfeed.
|
||||
*/
|
||||
private static final StrMatcher SPLIT_MATCHER = new CharSetMatcher(" \t\n\r\f".toCharArray());
|
||||
/**
|
||||
* Matches the String trim() whitespace characters.
|
||||
*/
|
||||
private static final StrMatcher TRIM_MATCHER = new TrimMatcher();
|
||||
/**
|
||||
* Matches the double quote character.
|
||||
*/
|
||||
private static final StrMatcher SINGLE_QUOTE_MATCHER = new CharMatcher('\'');
|
||||
/**
|
||||
* Matches the double quote character.
|
||||
*/
|
||||
private static final StrMatcher DOUBLE_QUOTE_MATCHER = new CharMatcher('"');
|
||||
/**
|
||||
* Matches the single or double quote character.
|
||||
*/
|
||||
private static final StrMatcher QUOTE_MATCHER = new CharSetMatcher("'\"".toCharArray());
|
||||
/**
|
||||
* Matches no characters.
|
||||
*/
|
||||
private static final StrMatcher NONE_MATCHER = new NoMatcher();
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a matcher which matches the comma character.
|
||||
*
|
||||
* @return a matcher for a comma
|
||||
*/
|
||||
public static StrMatcher commaMatcher() {
|
||||
return COMMA_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a matcher which matches the tab character.
|
||||
*
|
||||
* @return a matcher for a tab
|
||||
*/
|
||||
public static StrMatcher tabMatcher() {
|
||||
return TAB_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a matcher which matches the space character.
|
||||
*
|
||||
* @return a matcher for a space
|
||||
*/
|
||||
public static StrMatcher spaceMatcher() {
|
||||
return SPACE_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the same characters as StringTokenizer,
|
||||
* namely space, tab, newline and formfeed.
|
||||
*
|
||||
* @return the split matcher
|
||||
*/
|
||||
public static StrMatcher splitMatcher() {
|
||||
return SPLIT_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the String trim() whitespace characters.
|
||||
*
|
||||
* @return the trim matcher
|
||||
*/
|
||||
public static StrMatcher trimMatcher() {
|
||||
return TRIM_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a matcher which matches the single quote character.
|
||||
*
|
||||
* @return a matcher for a single quote
|
||||
*/
|
||||
public static StrMatcher singleQuoteMatcher() {
|
||||
return SINGLE_QUOTE_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a matcher which matches the double quote character.
|
||||
*
|
||||
* @return a matcher for a double quote
|
||||
*/
|
||||
public static StrMatcher doubleQuoteMatcher() {
|
||||
return DOUBLE_QUOTE_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a matcher which matches the single or double quote character.
|
||||
*
|
||||
* @return a matcher for a single or double quote
|
||||
*/
|
||||
public static StrMatcher quoteMatcher() {
|
||||
return QUOTE_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches no characters.
|
||||
*
|
||||
* @return a matcher that matches nothing
|
||||
*/
|
||||
public static StrMatcher noneMatcher() {
|
||||
return NONE_MATCHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that creates a matcher from a character.
|
||||
*
|
||||
* @param ch the character to match, must not be null
|
||||
* @return a new Matcher for the given char
|
||||
*/
|
||||
public static StrMatcher charMatcher(char ch) {
|
||||
return new CharMatcher(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that creates a matcher from a set of characters.
|
||||
*
|
||||
* @param chars the characters to match, null or empty matches nothing
|
||||
* @return a new matcher for the given char[]
|
||||
*/
|
||||
public static StrMatcher charSetMatcher(char[] chars) {
|
||||
if (chars == null || chars.length == 0) {
|
||||
return NONE_MATCHER;
|
||||
}
|
||||
if (chars.length == 1) {
|
||||
return new CharMatcher(chars[0]);
|
||||
}
|
||||
return new CharSetMatcher(chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that creates a matcher from a string representing a set of characters.
|
||||
*
|
||||
* @param chars the characters to match, null or empty matches nothing
|
||||
* @return a new Matcher for the given characters
|
||||
*/
|
||||
public static StrMatcher charSetMatcher(String chars) {
|
||||
if (chars == null || chars.length() == 0) {
|
||||
return NONE_MATCHER;
|
||||
}
|
||||
if (chars.length() == 1) {
|
||||
return new CharMatcher(chars.charAt(0));
|
||||
}
|
||||
return new CharSetMatcher(chars.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that creates a matcher from a string.
|
||||
*
|
||||
* @param str the string to match, null or empty matches nothing
|
||||
* @return a new Matcher for the given String
|
||||
*/
|
||||
public static StrMatcher stringMatcher(String str) {
|
||||
if (str == null || str.length() == 0) {
|
||||
return NONE_MATCHER;
|
||||
}
|
||||
return new StringMatcher(str);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
protected StrMatcher() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of matching characters, zero for no match.
|
||||
* <p>
|
||||
* This method is called to check for a match.
|
||||
* The parameter <code>pos</code> represents the current position to be
|
||||
* checked in the string <code>buffer</code> (a character array which must
|
||||
* not be changed).
|
||||
* The API guarantees that <code>pos</code> is a valid index for <code>buffer</code>.
|
||||
* <p>
|
||||
* The character array may be larger than the active area to be matched.
|
||||
* Only values in the buffer between the specifed indices may be accessed.
|
||||
* <p>
|
||||
* The matching code may check one character or many.
|
||||
* It may check characters preceeding <code>pos</code> as well as those
|
||||
* after, so long as no checks exceed the bounds specified.
|
||||
* <p>
|
||||
* It must return zero for no match, or a positive number if a match was found.
|
||||
* The number indicates the number of characters that matched.
|
||||
*
|
||||
* @param buffer the text content to match against, do not change
|
||||
* @param pos the starting position for the match, valid for buffer
|
||||
* @param bufferStart the first active index in the buffer, valid for buffer
|
||||
* @param bufferEnd the end index (exclusive) of the active buffer, valid for buffer
|
||||
* @return the number of matching characters, zero for no match
|
||||
*/
|
||||
public abstract int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Class used to define a set of characters for matching purposes.
|
||||
*/
|
||||
static final class CharSetMatcher extends StrMatcher {
|
||||
/** The set of characters to match. */
|
||||
private char[] chars;
|
||||
|
||||
/**
|
||||
* Constructor that creates a matcher from a character array.
|
||||
*
|
||||
* @param chars the characters to match, must not be null
|
||||
*/
|
||||
CharSetMatcher(char chars[]) {
|
||||
super();
|
||||
this.chars = (char[]) chars.clone();
|
||||
Arrays.sort(this.chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the given charatcer matches.
|
||||
*
|
||||
* @param buffer the text content to match against, do not change
|
||||
* @param pos the starting position for the match, valid for buffer
|
||||
* @param bufferStart the first active index in the buffer, valid for buffer
|
||||
* @param bufferEnd the end index of the active buffer, valid for buffer
|
||||
* @return the number of matching characters, zero for no match
|
||||
*/
|
||||
public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
|
||||
return Arrays.binarySearch(chars, buffer[pos]) >= 0 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Class used to define a character for matching purposes.
|
||||
*/
|
||||
static final class CharMatcher extends StrMatcher {
|
||||
/** The character to match. */
|
||||
private char ch;
|
||||
|
||||
/**
|
||||
* Constructor that creates a matcher that matches a single character.
|
||||
*
|
||||
* @param ch the character to match
|
||||
*/
|
||||
CharMatcher(char ch) {
|
||||
super();
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the given character matches.
|
||||
*
|
||||
* @param buffer the text content to match against, do not change
|
||||
* @param pos the starting position for the match, valid for buffer
|
||||
* @param bufferStart the first active index in the buffer, valid for buffer
|
||||
* @param bufferEnd the end index of the active buffer, valid for buffer
|
||||
* @return the number of matching characters, zero for no match
|
||||
*/
|
||||
public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
|
||||
return ch == buffer[pos] ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Class used to define a set of characters for matching purposes.
|
||||
*/
|
||||
static final class StringMatcher extends StrMatcher {
|
||||
/** The string to match, as a character array. */
|
||||
private char[] chars;
|
||||
|
||||
/**
|
||||
* Constructor that creates a matcher from a String.
|
||||
*
|
||||
* @param str the string to match, must not be null
|
||||
*/
|
||||
StringMatcher(String str) {
|
||||
super();
|
||||
chars = str.toCharArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the given text matches the stored string.
|
||||
*
|
||||
* @param buffer the text content to match against, do not change
|
||||
* @param pos the starting position for the match, valid for buffer
|
||||
* @param bufferStart the first active index in the buffer, valid for buffer
|
||||
* @param bufferEnd the end index of the active buffer, valid for buffer
|
||||
* @return the number of matching characters, zero for no match
|
||||
*/
|
||||
public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
|
||||
int len = chars.length;
|
||||
if (pos + len > bufferEnd) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < chars.length; i++, pos++) {
|
||||
if (chars[i] != buffer[pos]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Class used to match no characters.
|
||||
*/
|
||||
static final class NoMatcher extends StrMatcher {
|
||||
|
||||
/**
|
||||
* Constructs a new instance of <code>NoMatcher</code>.
|
||||
*/
|
||||
NoMatcher() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns <code>false</code>.
|
||||
*
|
||||
* @param buffer the text content to match against, do not change
|
||||
* @param pos the starting position for the match, valid for buffer
|
||||
* @param bufferStart the first active index in the buffer, valid for buffer
|
||||
* @param bufferEnd the end index of the active buffer, valid for buffer
|
||||
* @return the number of matching characters, zero for no match
|
||||
*/
|
||||
public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Class used to match whitespace as per trim().
|
||||
*/
|
||||
static final class TrimMatcher extends StrMatcher {
|
||||
|
||||
/**
|
||||
* Constructs a new instance of <code>TrimMatcher</code>.
|
||||
*/
|
||||
TrimMatcher() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the given charatcer matches.
|
||||
*
|
||||
* @param buffer the text content to match against, do not change
|
||||
* @param pos the starting position for the match, valid for buffer
|
||||
* @param bufferStart the first active index in the buffer, valid for buffer
|
||||
* @param bufferEnd the end index of the active buffer, valid for buffer
|
||||
* @return the number of matching characters, zero for no match
|
||||
*/
|
||||
public int isMatch(char[] buffer, int pos, int bufferStart, int bufferEnd) {
|
||||
return buffer[pos] <= 32 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Copyright 2005 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.lang.text;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import junit.textui.TestRunner;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link org.apache.commons.lang.text.StrMatcher}.
|
||||
*
|
||||
* @version $Id$
|
||||
*/
|
||||
public class StrMatcherTest extends TestCase {
|
||||
|
||||
private static final char[] BUFFER1 = "0,1\t2 3\n\r\f\u0000'\"".toCharArray();
|
||||
|
||||
private static final char[] BUFFER2 = "abcdef".toCharArray();
|
||||
|
||||
/**
|
||||
* Main method.
|
||||
*
|
||||
* @param args command line arguments, ignored
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
TestRunner.run(suite());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new test suite containing this test case.
|
||||
*
|
||||
* @return a new test suite containing this test case
|
||||
*/
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite(StrMatcherTest.class);
|
||||
suite.setName("StrMatcher Tests");
|
||||
return suite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new test case with the specified name.
|
||||
*
|
||||
* @param name the name
|
||||
*/
|
||||
public StrMatcherTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testCommaMatcher() {
|
||||
StrMatcher matcher = StrMatcher.commaMatcher();
|
||||
assertSame(matcher, StrMatcher.commaMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 0, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 1, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 2, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testTabMatcher() {
|
||||
StrMatcher matcher = StrMatcher.tabMatcher();
|
||||
assertSame(matcher, StrMatcher.tabMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 2, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 3, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 4, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testSpaceMatcher() {
|
||||
StrMatcher matcher = StrMatcher.spaceMatcher();
|
||||
assertSame(matcher, StrMatcher.spaceMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 4, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 5, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 6, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testSplitMatcher() {
|
||||
StrMatcher matcher = StrMatcher.splitMatcher();
|
||||
assertSame(matcher, StrMatcher.splitMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 2, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 3, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 4, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 5, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 6, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 7, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 8, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 9, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 10, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testTrimMatcher() {
|
||||
StrMatcher matcher = StrMatcher.trimMatcher();
|
||||
assertSame(matcher, StrMatcher.trimMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 2, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 3, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 4, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 5, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 6, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 7, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 8, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 9, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 10, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testSingleQuoteMatcher() {
|
||||
StrMatcher matcher = StrMatcher.singleQuoteMatcher();
|
||||
assertSame(matcher, StrMatcher.singleQuoteMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 10, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 11, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 12, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testDoubleQuoteMatcher() {
|
||||
StrMatcher matcher = StrMatcher.doubleQuoteMatcher();
|
||||
assertSame(matcher, StrMatcher.doubleQuoteMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 11, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 12, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testQuoteMatcher() {
|
||||
StrMatcher matcher = StrMatcher.quoteMatcher();
|
||||
assertSame(matcher, StrMatcher.quoteMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 10, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 11, 0, BUFFER1.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER1, 12, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testNoneMatcher() {
|
||||
StrMatcher matcher = StrMatcher.noneMatcher();
|
||||
assertSame(matcher, StrMatcher.noneMatcher());
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 0, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 1, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 2, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 3, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 4, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 5, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 6, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 7, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 8, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 9, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 10, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 11, 0, BUFFER1.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER1, 12, 0, BUFFER1.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testCharMatcher_char() {
|
||||
StrMatcher matcher = StrMatcher.charMatcher('c');
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 0, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 1, 0, BUFFER2.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER2, 2, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 3, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 4, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 5, 0, BUFFER2.length));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testCharSetMatcher_String() {
|
||||
StrMatcher matcher = StrMatcher.charSetMatcher("ace");
|
||||
assertEquals(1, matcher.isMatch(BUFFER2, 0, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 1, 0, BUFFER2.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER2, 2, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 3, 0, BUFFER2.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER2, 4, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 5, 0, BUFFER2.length));
|
||||
assertSame(StrMatcher.noneMatcher(), StrMatcher.charSetMatcher(""));
|
||||
assertSame(StrMatcher.noneMatcher(), StrMatcher.charSetMatcher((String) null));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testCharSetMatcher_charArray() {
|
||||
StrMatcher matcher = StrMatcher.charSetMatcher("ace".toCharArray());
|
||||
assertEquals(1, matcher.isMatch(BUFFER2, 0, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 1, 0, BUFFER2.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER2, 2, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 3, 0, BUFFER2.length));
|
||||
assertEquals(1, matcher.isMatch(BUFFER2, 4, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 5, 0, BUFFER2.length));
|
||||
assertSame(StrMatcher.noneMatcher(), StrMatcher.charSetMatcher(new char[0]));
|
||||
assertSame(StrMatcher.noneMatcher(), StrMatcher.charSetMatcher((char[]) null));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testStringMatcher_String() {
|
||||
StrMatcher matcher = StrMatcher.stringMatcher("bc");
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 0, 0, BUFFER2.length));
|
||||
assertEquals(2, matcher.isMatch(BUFFER2, 1, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 2, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 3, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 4, 0, BUFFER2.length));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 5, 0, BUFFER2.length));
|
||||
assertSame(StrMatcher.noneMatcher(), StrMatcher.stringMatcher(""));
|
||||
assertSame(StrMatcher.noneMatcher(), StrMatcher.stringMatcher((String) null));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
public void testMatcherIndices() {
|
||||
// remember that the API contract is tight for the isMatch() method
|
||||
// all the onus is on the caller, so invalid inputs are not
|
||||
// the concern of StrMatcher, and are not bugs
|
||||
StrMatcher matcher = StrMatcher.stringMatcher("bc");
|
||||
assertEquals(2, matcher.isMatch(BUFFER2, 1, 1, BUFFER2.length));
|
||||
assertEquals(2, matcher.isMatch(BUFFER2, 1, 0, 3));
|
||||
assertEquals(0, matcher.isMatch(BUFFER2, 1, 0, 2));
|
||||
}
|
||||
|
||||
}
|
|
@ -49,6 +49,8 @@ public static Test suite() {
|
|||
TestSuite suite = new TestSuite();
|
||||
suite.setName("Commons-Lang-Text Tests");
|
||||
suite.addTest(StrBuilderTest.suite());
|
||||
suite.addTest(StrBuilderAppendInsertTest.suite());
|
||||
suite.addTest(StrMatcherTest.suite());
|
||||
suite.addTest(StrTokenizerTest.suite());
|
||||
suite.addTestSuite(VariableFormatterTest.class);
|
||||
return suite;
|
||||
|
|
Loading…
Reference in New Issue