This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git
The following commit(s) were added to refs/heads/master by this push:
new 8d36cab7c Add
org.apache.commons.lang3.StringUtils.indexOfAny(CharSequence, int, char...)
8d36cab7c is described below
commit 8d36cab7c456e3db1e903931523f7abe00207805
Author: ggregory <[email protected]>
AuthorDate: Tue Aug 19 10:38:08 2025 -0400
Add org.apache.commons.lang3.StringUtils.indexOfAny(CharSequence, int,
char...)
---
src/changes/changes.xml | 1 +
.../java/org/apache/commons/lang3/StringUtils.java | 32 +++++++++++++++++-
.../lang3/StringUtilsEqualsIndexOfTest.java | 38 ++++++++++++++++++++--
3 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 202ed00c7..305fcc4e2 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -64,6 +64,7 @@ The <action> type attribute can be add,update,fix,remove.
<action type="add" dev="ggregory" due-to="Gary
Gregory">Add org.apache.commons.lang3.SystemUtils.IS_OS_NETWARE.</action>
<action type="add" dev="ggregory" due-to="Gary
Gregory">Add
org.apache.commons.lang3.reflect.MethodUtils.getAccessibleMethod(Class,
Method).</action>
<action type="add" dev="ggregory" due-to="Gary
Gregory">Add documentation to site for CVE-2025-48924 ClassUtils.getClass(...)
can throw a StackOverflowError on very long inputs.</action>
+ <action type="add" dev="ggregory" due-to="Gary
Gregory">Add org.apache.commons.lang3.StringUtils.indexOfAny(CharSequence, int,
char...).</action>
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory">[test] Bump
org.apache.commons:commons-text from 1.13.1 to 1.14.0.</action>
</release>
diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java
b/src/main/java/org/apache/commons/lang3/StringUtils.java
index 6076d7194..6c43ea3b4 100644
--- a/src/main/java/org/apache/commons/lang3/StringUtils.java
+++ b/src/main/java/org/apache/commons/lang3/StringUtils.java
@@ -2705,6 +2705,36 @@ public static int indexOf(final CharSequence seq, final
int searchChar, final in
* @since 3.0 Changed signature from indexOfAny(String, char[]) to
indexOfAny(CharSequence, char...)
*/
public static int indexOfAny(final CharSequence cs, final char...
searchChars) {
+ return indexOfAny(cs, 0, searchChars);
+ }
+
+ /**
+ * Search a CharSequence to find the first index of any character in the
given set of characters.
+ *
+ * <p>
+ * A {@code null} String will return {@code -1}. A {@code null} or zero
length search array will return {@code -1}.
+ * </p>
+ * <p>
+ * The following is the same as {@code indexOfAny(cs, 0, searchChars)}.
+ * </p>
+ * <pre>
+ * StringUtils.indexOfAny(null, 0, *) = -1
+ * StringUtils.indexOfAny("", 0, *) = -1
+ * StringUtils.indexOfAny(*, 0, null) = -1
+ * StringUtils.indexOfAny(*, 0, []) = -1
+ * StringUtils.indexOfAny("zzabyycdxx", 0, ['z', 'a']) = 0
+ * StringUtils.indexOfAny("zzabyycdxx", 0, ['b', 'y']) = 3
+ * StringUtils.indexOfAny("aba", 0, ['z']) = -1
+ * </pre>
+ *
+ * @param cs the CharSequence to check, may be null.
+ * @param csStart Start searching the input {@code cs} at this index.
+ * @param searchChars the chars to search for, may be null.
+ * @return the index of any of the chars, -1 if no match or null input.
+ * @since 2.0
+ * @since 3.0 Changed signature from indexOfAny(String, char[]) to
indexOfAny(CharSequence, char...)
+ */
+ public static int indexOfAny(final CharSequence cs, final int csStart,
final char... searchChars) {
if (isEmpty(cs) || ArrayUtils.isEmpty(searchChars)) {
return INDEX_NOT_FOUND;
}
@@ -2712,7 +2742,7 @@ public static int indexOfAny(final CharSequence cs, final
char... searchChars) {
final int csLast = csLen - 1;
final int searchLen = searchChars.length;
final int searchLast = searchLen - 1;
- for (int i = 0; i < csLen; i++) {
+ for (int i = csStart; i < csLen; i++) {
final char ch = cs.charAt(i);
for (int j = 0; j < searchLen; j++) {
if (searchChars[j] == ch) {
diff --git
a/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java
b/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java
index 7eec72ec5..26409ac2c 100644
--- a/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java
+++ b/src/test/java/org/apache/commons/lang3/StringUtilsEqualsIndexOfTest.java
@@ -388,11 +388,9 @@ void testIndexOfAny_StringCharArray() {
assertEquals(-1, StringUtils.indexOfAny(null, (char[]) null));
assertEquals(-1, StringUtils.indexOfAny(null, new char[0]));
assertEquals(-1, StringUtils.indexOfAny(null, 'a', 'b'));
-
assertEquals(-1, StringUtils.indexOfAny("", (char[]) null));
assertEquals(-1, StringUtils.indexOfAny("", new char[0]));
assertEquals(-1, StringUtils.indexOfAny("", 'a', 'b'));
-
assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", (char[]) null));
assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", new char[0]));
assertEquals(0, StringUtils.indexOfAny("zzabyycdxx", 'z', 'a'));
@@ -404,6 +402,42 @@ void testIndexOfAny_StringCharArray() {
assertEquals(0, StringUtils.indexOfAny("cbda", 'a', 'b', 'c', 'd'));
}
+ @Test
+ void testIndexOfAny_StringIntCharArray() {
+ // default cases
+ assertEquals(-1, StringUtils.indexOfAny(null, 0, (char[]) null));
+ assertEquals(-1, StringUtils.indexOfAny(null, 0, new char[0]));
+ assertEquals(-1, StringUtils.indexOfAny(null, 0, 'a', 'b'));
+ assertEquals(-1, StringUtils.indexOfAny("", 0, (char[]) null));
+ assertEquals(-1, StringUtils.indexOfAny("", 0, new char[0]));
+ assertEquals(-1, StringUtils.indexOfAny("", 0, 'a', 'b'));
+ assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 0, (char[])
null));
+ assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 0, new char[0]));
+ assertEquals(0, StringUtils.indexOfAny("zzabyycdxx", 0, 'z', 'a'));
+ assertEquals(3, StringUtils.indexOfAny("zzabyycdxx", 0, 'b', 'y'));
+ assertEquals(-1, StringUtils.indexOfAny("ab", 0, 'z'));
+ // if more than one search char is present, the order of the search
chars matters:
+ assertEquals(0, StringUtils.indexOfAny("abcd", 0, 'a', 'b', 'c', 'd'));
+ assertEquals(0, StringUtils.indexOfAny("bcda", 0, 'a', 'b', 'c', 'd'));
+ assertEquals(0, StringUtils.indexOfAny("cbda", 0, 'a', 'b', 'c', 'd'));
+ // Actually use the index
+ assertEquals(-1, StringUtils.indexOfAny(null, 1, (char[]) null));
+ assertEquals(-1, StringUtils.indexOfAny(null, 1, new char[0]));
+ assertEquals(-1, StringUtils.indexOfAny(null, 1, 'a', 'b'));
+ assertEquals(-1, StringUtils.indexOfAny("", 1, (char[]) null));
+ assertEquals(-1, StringUtils.indexOfAny("", 1, new char[0]));
+ assertEquals(-1, StringUtils.indexOfAny("", 1, 'a', 'b'));
+ assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 1, (char[])
null));
+ assertEquals(-1, StringUtils.indexOfAny("zzabyycdxx", 1, new char[0]));
+ assertEquals(1, StringUtils.indexOfAny("zzabyycdxx", 1, 'z', 'a'));
+ assertEquals(3, StringUtils.indexOfAny("zzabyycdxx", 1, 'b', 'y'));
+ assertEquals(-1, StringUtils.indexOfAny("ab", 1, 'z'));
+ // if more than one search char is present, the order of the search
chars matters:
+ assertEquals(1, StringUtils.indexOfAny("abcd", 1, 'a', 'b', 'c', 'd'));
+ assertEquals(1, StringUtils.indexOfAny("bcda", 1, 'a', 'b', 'c', 'd'));
+ assertEquals(1, StringUtils.indexOfAny("cbda", 1, 'a', 'b', 'c', 'd'));
+ }
+
/**
* See
https://www.oracle.com/technical-resources/articles/javase/supplementary.html
*/