@@ -80,8 +80,10 @@ public static boolean equalsChar(final char expected, final CharSequence s) {
8080 }
8181
8282 /**
83+ * Tests if a CharSequence starts with a specified prefix.
84+ *
8385 * @param s the string to check
84- * @param expectedStart the string that we expect at the beginning
86+ * @param expectedStart the string that we expect at the beginning (has to be not null and not empty)
8587 * @return true if the provided string has only one char and this matches the expectation
8688 */
8789 public static boolean startsWithIgnoreCase (final String s , final String expectedStart ) {
@@ -99,6 +101,66 @@ public static boolean startsWithIgnoreCase(final String s, final String expected
99101 return s .regionMatches (true , 0 , expectedStart , 0 , expectedStart .length ());
100102 }
101103
104+ /**
105+ * Tests if a CharSequence ends with a specified prefix.
106+ *
107+ * @param s the string to check
108+ * @param expectedEnd the string that we expect at the end (has to be not null and not empty)
109+ * @return true if the provided string has only one char and this matches the expectation
110+ */
111+ public static boolean endsWithIgnoreCase (final String s , final String expectedEnd ) {
112+ if (expectedEnd == null ) {
113+ throw new IllegalArgumentException ("Expected end string can't be null or empty" );
114+ }
115+
116+ final int expectedEndLength = expectedEnd .length ();
117+ if (expectedEndLength == 0 ) {
118+ throw new IllegalArgumentException ("Expected end string can't be null or empty" );
119+ }
120+
121+ if (s == null ) {
122+ return false ;
123+ }
124+ if (s == expectedEnd ) {
125+ return true ;
126+ }
127+
128+ return s .regionMatches (true , s .length () - expectedEndLength , expectedEnd , 0 , expectedEndLength );
129+ }
130+
131+ /**
132+ * Tests if a CharSequence ends with a specified prefix.
133+ *
134+ * @param s the string to check
135+ * @param expected the string that we expect to be a substring (has to be not null and not empty)
136+ * @return true if the provided string has only one char and this matches the expectation
137+ */
138+ public static boolean containsIgnoreCase (final String s , final String expected ) {
139+ if (expected == null ) {
140+ throw new IllegalArgumentException ("Expected string can't be null or empty" );
141+ }
142+
143+ final int expectedLength = expected .length ();
144+ if (expectedLength == 0 ) {
145+ throw new IllegalArgumentException ("Expected string can't be null or empty" );
146+ }
147+
148+ if (s == null ) {
149+ return false ;
150+ }
151+ if (s == expected ) {
152+ return true ;
153+ }
154+
155+ final int max = s .length () - expectedLength ;
156+ for (int i = 0 ; i <= max ; i ++) {
157+ if (s .regionMatches (true , i , expected , 0 , expectedLength )) {
158+ return true ;
159+ }
160+ }
161+ return false ;
162+ }
163+
102164 /**
103165 * Escapes the characters '<', '>' and '&' into their XML entity equivalents.
104166 *
0 commit comments