Проверка на наличие подстрок в строке – довольно распространенная задача в программировании. Например, иногда мы хотим разбить строку, если она содержит разделитель в точке. В других случаях мы хотим изменить поток, если строка содержит (или не имеет) определенную подстроку, которая может быть командой.
Есть несколько способов сделать это в Java, и большинство из них – то, что вы ожидаете увидеть и в других языках программирования. Однако один из подходов, уникальных для Java, – это использование класса Pattern
, о котором мы расскажем позже в этой статье.
В качестве альтернативы вы можете использовать Apache Commons и вспомогательный класс StringUtils
, который предлагает множество производных методов из основных методов для этой цели.
Основные способы Java
String.contains()
Первый и главный способ проверить наличие подстроки – это метод .contains()
. Это обеспечивается самим классом String
и очень эффективно.
Метод принимает CharSequence
и возвращает true
, если последовательность присутствует в строке, для которой мы вызываем метод:
String string = "Java";
String substring = "va";
System.out.println(string.contains(substring));
Запуск этого даст:
Примечание: метод .contains()
чувствителен к регистру. Если бы мы попытались искать "Va"
в нашем string
, результат будет false
.
Часто, чтобы избежать этой проблемы, так как мы не хотим быть чувствительны к регистру, вы должны сопоставить регистр обеих строк перед проверкой:
System.out.println(string.toLowerCase().contains(substring.toLowerCase()));
// OR
System.out.println(string.toUpperCase().contains(substring.toUpperCase()));
String.indexOf()
Метод .indexOf()
возвращает индекс первого вхождения подстроки в строке и предлагает несколько конструкторов на выбор:
indexOf(int ch)
indexOf(int ch, int fromIndex)
indexOf(String str)
indexOf(String str, int fromIndex)
Мы можем либо искать один символ со смещением или без него, либо искать строку со смещением или без него.
Метод вернет индекс первого вхождения, если присутствует, и -1
если нет:
String string = "Lorem ipsum dolor sit amet.";
// You can also use unicode for characters
System.out.println(string.indexOf('i'));
System.out.println(string.indexOf('i', 8));
System.out.println(string.indexOf("dolor"));
System.out.println(string.indexOf("Lorem", 10));
Запуск этого кода даст:
- Первое вхождение
i
в словеipsum
, имеет индекс 6 от начала последовательности символов. - Первое вхождение
i
со смещением8
находится в словеsit
, имеет индекс 19 от начала. - Первое вхождение String
dolor
– имеет индекс 12 с начала. - И, наконец, слова
Lorem
нет при смещении10
.
В конечном счете, метод .contains()
внутри себя вызывает метод .indexOf()
. Это делает .indexOf()
даже более эффективным, чем аналог (хотя и очень небольшой), хотя у него есть несколько иной вариант использования.
String.lastIndexOf()
В отличие от метода .indexOf()
, который возвращает первое вхождение, метод .lastIndexOf()
возвращает индекс последнего вхождения символа или строки со смещением или без него:
String string = "Lorem ipsum dolor sit amet.";
// You can also use unicode for characters
System.out.println(string.lastIndexOf('i'));
System.out.println(string.lastIndexOf('i', 8));
System.out.println(string.lastIndexOf("dolor"));
System.out.println(string.lastIndexOf("Lorem", 10));
Запуск этого кода даст:
Некоторые могут быть немного удивлены результатами и скажут:
lastIndexOf('i', 8)
должен был вернуть 19
, так как это последнее вхождение символа после 8-го символа в строке
Стоит отметить, что при запуске метода .lastIndexOf()
последовательность символов меняется на противоположную. Отсчет начинается с последнего символа и идет к первому.
Это, как говорится – ожидаемый результат – 6
последнее появление символа после пропуска 8 элементов из конца последовательности.
Шаблон с регулярным выражением и Matcher
Класс Pattern
существенно скомпилированное представление регулярного выражения. Он используется вместе с классом Matcher
для сопоставления последовательностей символов.
Этот класс в первую очередь работает путем компиляции шаблона. Затем мы присваиваем другой шаблон экземпляру Matcher
, который использует метод .find()
для сравнения назначенных и скомпилированных шаблонов.
Если они совпадают, метод .find()
приводит к true
. Если шаблоны не совпадают, метод приводит к false
.
Pattern pattern = Pattern.compile(".*" + "some" + ".*");
Matcher matcher = pattern.matcher("Here is some pattern!");
System.out.println(matcher.find());
Это даст:
Apache Commons
Из-за его полезности и распространенности в Java, во многих проектах Apache Commons включен в classpath. Это отличная библиотека со многими полезными функциями, часто используемыми в производстве, и проверка подстрок не является исключением.
Apache Commons предлагает класс StringUtils
со многими вспомогательными методами для манипуляций со строками, нуль-проверка и т.д. Для решения этой задачи, мы можем использовать любого из методов .contains()
, .indexOf()
, .lastIndexOf()
или .containsIgnoreCase()
.
Если нет, то это так же просто, как добавить зависимость к вашему файлу pom.xml
, если вы используете Maven:
org.apache.commons
commons-lang3
{version}
Или добавив его через Gradle:
compile group: 'org.apache.commons', name: 'commons-lang3', version: '{version}'
StringUtils.contains()
Метод .contains()
довольно прост и очень похож на основной Java подход.
Единственное отличие состоит в том, что мы не вызываем метод для проверяемой строки (поскольку он не наследует этот метод), а вместо этого передаем искомую строку вместе со строкой, которую мы ищем:
String string = "Checking for substrings within a String is a fairly common task in programming.";
System.out.println(StringUtils.contains(string, "common task"));
Запуск этого кода даст:
Примечание: этот метод чувствителен к регистру.
StringUtils.indexOf()
Естественно, метод .indexOf()
также работает очень похоже на основной подход Java:
String string = "Checking for substrings within a String is a fairly common task in programming.";
// Search for first occurrence of 'f'
System.out.println(StringUtils.indexOf(string, 'f'));
// Search for first occurrence of 'f', skipping the first 12 elements
System.out.println(StringUtils.indexOf(string, 'f', 12));
// Search for the first occurrence of the "String" string
System.out.println(StringUtils.indexOf(string, "String"));
Запуск этого кода даст:
StringUtils.indexOfAny()
Метод .indexOfAny()
принимает список символов, а не один, что позволяет нам искать первое вхождение любого из переданных символов:
String string = "Checking for substrings within a String is a fairly common task in programming.";
// Search for first occurrence of 'f' or 'n', whichever comes first
System.out.println(StringUtils.indexOfAny(string, 'f', 'n'));
// Search for the first occurrence of "String" or "for", whichever comes first
System.out.println(StringUtils.indexOfAny(string, "String", "for"));
Запуск этого кода даст:
StringUtils.indexOfAnyBut()
Метод .indexOfAnyBut()
ищет первое вхождение любого символа, что это не в предоставленном комплекте:
String string = "Checking for substrings within a String is a fairly common task in programming.";
// Search for first character outside of the provided set 'C' and 'h'
System.out.println(StringUtils.indexOfAny(string, 'C', 'h'));
// Search for first character outside of the provided set 'C' and 'h'
System.out.println(StringUtils.indexOfAny(string, "Checking", "for"));
Запуск этого кода даст:
StringUtils.indexOfDifference()
Метод .indexOfDifference()
сравнивает два массива символов, и возвращает индекс первого символа, отличающийся:
String s1 = "Hello World!"
String s2 = "Hello world!"
System.out.println(StringUtils.indexOfDifference(s1, s2));
Запуск этого кода даст:
StringUtils.indexOfIgnoreCase()
Метод .indexOfIgnoreCase()
возвращает индекс первого вхождения символа в последовательности символов, игнорируя случай:
String string = "Checking for substrings within a String is a fairly common task in programming."
System.out.println(StringUtils.indexOf(string, 'c'));
System.out.println(StringUtils.indexOfIgnoreCase(string, 'c'));
Запуск этого кода даст:
StringUtils.lastIndexOf()
И, наконец, метод .lastIndexOf()
работает почти так же, как обычный Java-метод:
String string = "Lorem ipsum dolor sit amet.";
// You can also use unicode for characters
System.out.println(StringUtils.lastIndexOf(string, 'i'));
System.out.println(StringUtils.lastIndexOf(string, 'i', 8));
System.out.println(StringUtils.lastIndexOf(string, "dolor"));
System.out.println(StringUtils.lastIndexOf(string, "Lorem", 10));
Запуск этого кода даст:
StringUtils.containsIgnoreCase()
В методе .containsIgnoreCase()
, проверяет содержит строка подстроку, не обращая внимания на случай:
String string = "Checking for substrings within a String is a fairly common task in programming.";
System.out.println(StringUtils.containsIgnoreCase(string, "cOmMOn tAsK"));
Запуск этого кода даст:
StringUtils.containsOnly()
Метод .containsOnly()
проверяет, если последовательность символов содержит только указанные значения.
Это может вводить в заблуждение, поэтому можно сказать, что это еще один способ – он проверяет, состоит ли последовательность символов только из указанных символов. Он принимает либо строку, либо последовательность символов:
String string = "Hello World!"
System.out.println(StringUtils.containsOnly(string, 'HleWord!'));
System.out.println(StringUtils.containsOnly(string, "wrld"));
Запуск этого даст:
Строка "Hello World!"
действительно построена только из символов в последовательности 'HleWord!'
.
Примечание: не все символы из последовательности необходимо использовать в методе string
для возврата true. Важно то, что в нем нет символа, которого нет в последовательности символов.
StringUtils.containsNone()
Метод .containsNone()
, содержит ли строка какой – либо из «запрещенных» символов из набора:
String string = "Hello World!"
System.out.println(StringUtils.containsNone(string, 'xmt'));
System.out.println(StringUtils.containsNone(string, "wrld"));
Запуск этого кода дает:
StringUtils.containsAny()
И наконец, метод .containsAny()
возвращает true
, если последовательность символов содержит какой-либо из переданных параметров в форме последовательности символов или строки:
String string = "Hello World!"
System.out.println(StringUtils.containsAny(string, 'h', 'm'));
System.out.println(StringUtils.containsAny(string, "hell"));
Этот код даст:
Strings are a very important aspect from a programming perspective as many questions can be framed out among strings. There arise wide varied sets of concepts and questions that are pivotal to understanding strings. Now over here will be discussing different ways to play with strings where we will be playing with characters with strings and substrings which is a part of input strings with help of inbuilt methods and also by proposing logic listing wide varied ways as follows:
Searching a Character in the String
Way 1: indexOf(char c)
It searches the index of specified characters within a given string. It starts searching from the beginning to the end of the string (from left to right) and returns the corresponding index if found otherwise returns -1.
Note: If the given string contains multiple occurrences of a specified character then it returns the index of the only first occurrence of the specified character.
Syntax:
int indexOf(char c) // Accepts character as argument, Returns index of // the first occurrence of specified character
Way 2: lastIndexOf(char c)
It starts searching backward from the end of the string and returns the index of specified characters whenever it is encountered.
Syntax:
public int lastIndexOf(char c) // Accepts character as argument, Returns an // index of the last occurrence specified // character
Way 3: indexOf(char c, int indexFrom)
It starts searching forward from the specified index in the string and returns the corresponding index when the specified character is encountered otherwise returns -1.
Note: The returned index must be greater than or equal to the specified index.
Syntax:
public int IndexOf(char c, int indexFrom)
Parameters:
- The character to be searched
- An integer from where searching
Return Type: An index of a specified character that appeared at or after the specified index in a forwarding direction.
Way 4: lastIndexOf(char c, int fromIndex)
It starts searching backward from the specified index in the string. And returns the corresponding index when the specified character is encountered otherwise returns -1.
Note: The returned index must be less than or equal to the specified index.
Syntax:
public int lastIndexOf(char c, int fromIndex)
Way 5: charAt(int indexNumber)
Returns the character existing at the specified index, indexNumber in the given string. If the specified index number does not exist in the string, the method throws an unchecked exception, StringIndexOutOfBoundsException.
Syntax:
char charAt(int indexNumber)
Example:
Java
import
java.io.*;
class
GFG {
public
static
void
main(String[] args)
{
String str
=
"GeeksforGeeks is a computer science portal"
;
int
firstIndex = str.indexOf(
's'
);
System.out.println(
"First occurrence of char 's'"
+
" is found at : "
+ firstIndex);
int
lastIndex = str.lastIndexOf(
's'
);
System.out.println(
"Last occurrence of char 's' is"
+
" found at : "
+ lastIndex);
int
first_in = str.indexOf(
's'
,
10
);
System.out.println(
"First occurrence of char 's'"
+
" after index 10 : "
+ first_in);
int
last_in = str.lastIndexOf(
's'
,
20
);
System.out.println(
"Last occurrence of char 's'"
+
" after index 20 is : "
+ last_in);
int
char_at = str.charAt(
20
);
System.out.println(
"Character at location 20: "
+ char_at);
}
}
Output
First occurrence of char 's' is found at : 4 Last occurrence of char 's' is found at : 28 First occurrence of char 's' after index 10 : 12 Last occurrence of char 's' after index 20 is : 15 Character at location 20: 111
Way 6: Searching Substring in the String
The methods used for searching a character in the string which are mentioned above can also be used for searching the substring in the string.
Example
Java
import
java.io.*;
class
GFG {
public
static
void
main(String[] args)
{
String str
=
"GeeksforGeeks is a computer science portal"
;
int
firstIndex = str.indexOf(
"Geeks"
);
System.out.println(
"First occurrence of char Geeks"
+
" is found at : "
+ firstIndex);
int
lastIndex = str.lastIndexOf(
"Geeks"
);
System.out.println(
"Last occurrence of char Geeks is"
+
" found at : "
+ lastIndex);
int
first_in = str.indexOf(
"Geeks"
,
10
);
System.out.println(
"First occurrence of char Geeks"
+
" after index 10 : "
+ first_in);
int
last_in = str.lastIndexOf(
"Geeks"
,
20
);
System.out.println(
"Last occurrence of char Geeks "
+
"after index 20 is : "
+ last_in);
}
}
Output
First occurrence of char Geeks is found at : 0 Last occurrence of char Geeks is found at : 8 First occurrence of char Geeks after index 10 : -1 Last occurrence of char Geeks after index 20 is : 8
Way 7: contains(CharSequence seq): It returns true if the string contains the specified sequence of char values otherwise returns false. Its parameters specify the sequence of characters to be searched and throw NullPointerException if seq is null.
Syntax:
public boolean contains(CharSequence seq)
Note: CharSequence is an interface that is implemented by String class, Therefore we use string as an argument in contains() method.
Example
Java
import
java.io.*;
import
java.lang.*;
class
GFG {
public
static
void
main(String[] args)
{
String test =
"software"
;
CharSequence seq =
"soft"
;
boolean
bool = test.contains(seq);
System.out.println(
"Found soft?: "
+ bool);
boolean
seqFound = test.contains(
"war"
);
System.out.println(
"Found war? "
+ seqFound);
boolean
sqFound = test.contains(
"wr"
);
System.out.println(
"Found wr?: "
+ sqFound);
}
}
Output
Found soft?: true Found war? true Found wr?: false
Way 8: Matching String Start and End
- boolean startsWith(String str): Returns true if the string str exists at the starting of the given string, else false.
- boolean startsWith(String str, int indexNum): Returns true if the string str exists at the starting of the index indexNum in the given string, else false.
- boolean endsWith(String str): Returns true if the string str exists at the ending of the given string, else false.
Example:
Java
import
java.io.*;
class
GFG {
public
static
void
main(String[] args)
{
String str
=
"GeeksforGeeks is a computer science portal"
;
System.out.println(str.startsWith(
"Geek"
));
System.out.println(str.startsWith(
"is"
,
14
));
System.out.println(str.endsWith(
"port"
));
}
}
This article is contributed by Nitsdheerendra. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Last Updated :
16 Feb, 2023
Like Article
Save Article
Looking back at the original question, we need to find some given keywords in a given sentence, count the number of occurrences and know something about where. I don’t quite understand what “where” means (is it an index in the sentence?), so I’ll pass that one… I’m still learning java, one step at a time, so I’ll see to that one in due time 🙂
It must be noticed that common sentences (as the one in the original question) can have repeated keywords, therefore the search cannot just ask if a given keyword “exists or not” and count it as 1 if it does exist. There can be more then one of the same. For example:
// Base sentence (added punctuation, to make it more interesting):
String sentence = "Say that 123 of us will come by and meet you, "
+ "say, at the woods of 123woods.";
// Split it (punctuation taken in consideration, as well):
java.util.List<String> strings =
java.util.Arrays.asList(sentence.split(" |,|\."));
// My keywords:
java.util.ArrayList<String> keywords = new java.util.ArrayList<>();
keywords.add("123woods");
keywords.add("come");
keywords.add("you");
keywords.add("say");
By looking at it, the expected result would be 5 for “Say” + “come” + “you” + “say” + “123woods”, counting “say” twice if we go lowercase. If we don’t, then the count should be 4, “Say” being excluded and “say” included. Fine. My suggestion is:
// Set... ready...?
int counter = 0;
// Go!
for(String s : strings)
{
// Asking if the sentence exists in the keywords, not the other
// around, to find repeated keywords in the sentence.
Boolean found = keywords.contains(s.toLowerCase());
if(found)
{
counter ++;
System.out.println("Found: " + s);
}
}
// Statistics:
if (counter > 0)
{
System.out.println("In sentence: " + sentence + "n"
+ "Count: " + counter);
}
And the results are:
Found: Say
Found: come
Found: you
Found: say
Found: 123woods
In sentence: Say that 123 of us will come by and meet you, say, at the woods of 123woods.
Count: 5
В этой статье мы рассмотрим операции со строкой и подстрокой. Вы узнаете, как соединять и сравнивать строки, как извлекать символы и подстроки, как выполнять поиск в строке.
Соединение строк в Java
Чтобы соединить строки в Java, подойдёт операция сложения “+”:
String str1 = "Java"; String str2 = "Hi"; String str3 = str1 + " " + str2; System.out.println(str3); // Hi JavaЕсли же в предстоящей операции сложения строк будет применяться нестроковый объект, допустим, число, данный объект преобразуется к строке:
String str3 = "Год " + 2020;По факту, когда мы складываем строки с нестроковыми объектами, вызывается метод valueOf() класса String. Этот метод преобразует к строке почти все типы данных. Чтобы преобразовать объекты разных классов, valueOf вызывает метод toString() данных классов.
Объединять строки можно и с помощью concat():
String str1 = "Java"; String str2 = "Hi"; str2 = str2.concat(str1); // HiJavaМетод принимает строку, с которой нужно объединить вызывающую строку, возвращая нам уже соединённую строку.
Также мы можем использовать метод join(), позволяющий объединять строки с учетом разделителя. Допустим, две строки выше слились в слово “HiJava”, однако мы бы хотели разделить подстроки пробелом. Тут и пригодится join():
String str1 = "Java"; String str2 = "Hi"; String str3 = String.join(" ", str2, str1); // Hi JavaМетод join — статический. Первый параметр — это разделитель, который будет использоваться для разделения подстрок в общей строке. Последующие параметры осуществляют передачу через запятую произвольного набора объединяемых подстрок — в нашем случае их две, но можно и больше.
Извлекаем символы и подстроки в Java
Чтобы извлечь символы по индексу, в классе String есть метод char charAt(int index). Этот метод принимает индекс, по которому необходимо получить символы, возвращая извлеченный символ:
String str = "Java"; char c = str.charAt(2); System.out.println(c); // vОбратите внимание, что индексация начинается с нуля, впрочем, как и в массивах.
Если же нужно извлечь сразу группу символов либо подстроку, подойдёт getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin). Этот метод принимает ряд параметров:
• srcBegin: индекс в нашей строке, с которого осуществляется начало извлечения символов;
• srcEnd: индекс в нашей строке, до которого осуществляется извлечение символов;
• dst: массив символов (именно в него будут эти символы извлекаться);
• dstBegin: индекс в массиве dst (с него надо добавлять символы, извлечённые из строки).String str = "Hi world!"; int start = 6; int end = 11; char[] dst=new char[end - start]; str.getChars(start, end, dst, 0); System.out.println(dst); // worldСравниваем строки в Java
Мы уже писали о том, как сравнивать строки в Java, используя для этого метод equals() (регистр учитывается) и equalsIgnoreCase() (регистр не учитывается). Хотелось бы сказать пару слов про ещё одну пару методов: int compareTo(String str) и int compareToIgnoreCase(String str) — они позволяют не только сравнить 2 строки, но и узнать, больше ли одна другой. Если значение, которое возвращается, больше 0, первая строка больше, если меньше нуля, всё наоборот. Когда обе строки равны, вернётся ноль.
Для определения используется лексикографический порядок. Допустим, строка “A” меньше строки “B”, ведь символ ‘A’ в алфавите находится перед символом ‘B’. Когда первые символы строк равны, в расчёт берутся следующие символы. К примеру:
String str1 = "hello"; String str2 = "world"; String str3 = "hell"; System.out.println(str1.compareTo(str2)); // -15 - str1 меньше, чем strt2 System.out.println(str1.compareTo(str3)); // 1 - str1 больше, чем str3Поиск в строке в Java
Чтобы найти индекс первого вхождения подстроки в строку, используют метод indexOf(), последнего — метод lastIndexOf(). Если подстрока не найдена, оба метода вернут -1:
String str = "Hello world"; int index1 = str.indexOf('l'); // 2 int index2 = str.indexOf("wo"); //6 int index3 = str.lastIndexOf('l'); //9Чтобы определить, начинается строка с определённой подстроки, применяют метод startsWith(). Что касается метода endsWith(), то он даёт возможность определить оканчивается ли строка на определенную подстроку:
String str = "myfile.exe"; boolean start = str.startsWith("my"); //true boolean end = str.endsWith("exe"); //trueВыполняем замену в строке в Java
Заменить в нашей строке одну последовательность символов другой можно с помощью метода replace():
String str = "Hello world"; String replStr1 = str.replace('l', 'd'); // Heddo wordd String replStr2 = str.replace("Hello", "Bye"); // Bye worldОбрезаем строки в Java
Для удаления начальных и конечных пробелов применяют метод trim():
String str = " hello world "; str = str.trim(); // hello worldТакже существует метод substring() — он возвращает подстроку, делая это с какого-нибудь конкретного индекса до конца либо до определённого индекса:
String str = "Hello world"; String substr1 = str.substring(6); // world String substr2 = str.substring(3,5); //loМеняем регистр в Java
При необходимости вы можете перевести все символы вашей строки в нижний регистр (toLowerCase()) или в верхний (toUpperCase()):
String str = "Hello World"; System.out.println(str.toLowerCase()); // hello world System.out.println(str.toUpperCase()); // HELLO WORLDSplit
С помощью этого метода вы сможете разбить строку на подстроки по конкретному разделителю. Под разделителем понимается какой-либо символ либо набор символов, передаваемые в метод в качестве параметра. Давайте для примера разобьём небольшой текст на отдельные слова:
String text = "OTUS is a good company"; String[] words = text.split(" "); for(String word : words){ System.out.println(word); }В нашем случае строка разделится по пробелу, и мы получим следующий консольный вывод:
Вот и всё! Узнать больше всегда можно на наших курсах:
При написании статьи использовались материалы:
1. «Java-примеры: найти последнее вхождение подстроки в строке».
2. «Основные операции со строками».
Introduction
Checking for substrings within a String is a fairly common task in programming. For example, sometimes we wish to break a String if it contains a delimiter at a point. Other times, we wish to alter the flow if a String contains (or lacks) a certain substring, which could be a command.
There’s a couple of ways to do this in Java, and most of them are what you’d expect to see in other programming languages as well. One approach that is unique to Java, however, is the use of a Pattern
class, which we’ll cover later in the article.
Alternatively, you can use Apache Commons and the helper class StringUtils
, which offers many derived methods from the core methods for this purpose.
Core Java
String.contains()
The first and foremost way to check for the presence of a substring is the .contains()
method. It’s provided by the String
class itself and is very efficient.
The method accepts a CharSequence
and returns true
if the sequence is present in the String we call the method on:
String string = "Java";
String substring = "va";
System.out.println(string.contains(substring));
Running this would yield:
true
Note: The .contains()
method is case sensitive. If we tried looking for "Va"
in our string
, the result would be false
.
Oftentimes, to avoid this issue, since we’re not looking for case sensitivity, you’d match the case of both Strings before checking:
System.out.println(string.toLowerCase().contains(substring.toLowerCase()));
// OR
System.out.println(string.toUpperCase().contains(substring.toUpperCase()));
String.indexOf()
The .indexOf()
method is a bit more crude than the .contains()
method, but it’s nevertheless the underlying mechanism that enables the .contains()
method to work.
It returns the index of the first occurrence of a substring within a String, and offers a few constructors to choose from:
indexOf(int ch)
indexOf(int ch, int fromIndex)
indexOf(String str)
indexOf(String str, int fromIndex)
We can either search for a single character with or without an offset or search for a String with or without an offset.
The method will return the index of the first occurrence if present, and -1
if not:
String string = "Lorem ipsum dolor sit amet.";
// You can also use unicode for characters
System.out.println(string.indexOf('i'));
System.out.println(string.indexOf('i', 8));
System.out.println(string.indexOf("dolor"));
System.out.println(string.indexOf("Lorem", 10));
Running this code will yield:
6
19
12
-1
- The first occurrence of
i
is in the wordipsum
, 6 places from the start of the character sequence. - The first occurrence of
i
with an offset of8
(i.e. the search starts ats
ofipsum
) is in thesit
word, 19 places from the start. - The first occurrence of the String
dolor
is 12 places from the start. - And finally, there is no occurrence of
Lorem
with an offset of10
.
Ultimately, the .contains()
method calls upon the .indexOf()
method to work. That makes .indexOf()
inherently even more efficient than the counterpart (albeit a very small amount) – though it does have a slightly different use-case.
String.lastIndexOf()
As opposed to the .indexOf()
method, which returns the first occurrence, the .lastIndexOf()
method returns the index of the last occurrence of a character or String, with or without an offset:
String string = "Lorem ipsum dolor sit amet.";
// You can also use unicode for characters
System.out.println(string.lastIndexOf('i'));
System.out.println(string.lastIndexOf('i', 8));
System.out.println(string.lastIndexOf("dolor"));
System.out.println(string.lastIndexOf("Lorem", 10));
Running this code will yield:
19
6
12
0
Some may be a bit surprised by the results and say:
lastIndexOf('i', 8)
should’ve returned19
as that’s the last occurrence of the character after the 8th character in the String
What’s worth noting is that when running the .lastIndexOf()
method, the character sequence is reversed. The counting starts at the final character and goes towards the first.
That being said – yes. The expected output is 6
, as that’s the last occurrence of the character after skipping 8 elements from the end of the sequence.
Pattern with Regex and Matcher
The Pattern
class is essentially a compiled representation of a regular expression. It’s used alongside the Matcher
class to match character sequences.
This class works by compiling a pattern first. We then assign another pattern to a Matcher
instance, which uses the .find()
method to compare the assigned and compiled patterns.
If they match, the .find()
method results in true
. If the patterns don’t match, the method results in false
.
Pattern pattern = Pattern.compile(".*" + "some" + ".*");
Matcher matcher = pattern.matcher("Here is some pattern!");
System.out.println(matcher.find());
This would yield:
true
Apache Commons
Due to its usefulness and prevalence in Java, many projects have Apache Commons included in the classpath. It’s a great library with many useful features often used in production – and checking for substrings is no exception.
Apache Commons offers the StringUtils
class with many helper methods for String manipulation, null-checking, etc. For this task, we can utilize any of the .contains()
, .indexOf()
, .lastIndexOf()
, or .containsIgnoreCase()
methods.
If not, including it is as easy as adding a dependency to your pom.xml
file if you’re using Maven:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>{version}</version>
</dependency>
Or by adding it through Gradle:
compile group: 'org.apache.commons', name: 'commons-lang3', version: '{version}'
StringUtils.contains()
The .contains()
method is pretty straightforward and very similar to the core Java approach.
The only difference is that we don’t call the method on the String we’re checking (as it doesn’t inherit this method), but rather pass the String we’re searching in alongside the String we’re searching for:
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
String string = "Checking for substrings within a String is a fairly common task in programming.";
System.out.println(StringUtils.contains(string, "common task"));
Running this code will yield:
true
Note: This method is case-sensitive.
StringUtils.indexOf()
Naturally, the .indexOf()
method also works very similarly to the core Java approach:
String string = "Checking for substrings within a String is a fairly common task in programming.";
// Search for first occurrence of 'f'
System.out.println(StringUtils.indexOf(string, 'f'));
// Search for first occurrence of 'f', skipping the first 12 elements
System.out.println(StringUtils.indexOf(string, 'f', 12));
// Search for the first occurrence of the "String" string
System.out.println(StringUtils.indexOf(string, "String"));
Running this code will yield:
9
45
32
StringUtils.indexOfAny()
The .indexOfAny()
method accepts a vararg of characters, instead of a single one, allowing us to search for the first occurrence of any of the passed characters:
String string = "Checking for substrings within a String is a fairly common task in programming.";
// Search for first occurrence of 'f' or 'n', whichever comes first
System.out.println(StringUtils.indexOfAny(string, ['f', 'n']));
// Search for the first occurrence of "String" or "for", whichever comes first
System.out.println(StringUtils.indexOfAny(string, "String", "for"));
Running this code will yield:
6
9
StringUtils.indexOfAnyBut()
The .indexOfAnyBut()
method searches for the first occurrence of any character that’s not in the provided set:
String string = "Checking for substrings within a String is a fairly common task in programming.";
// Search for first character outside of the provided set 'C' and 'h'
System.out.println(StringUtils.indexOfAny(string, ['C', 'h']));
// Search for first character outside of the provided set 'C' and 'h'
System.out.println(StringUtils.indexOfAny(string, ["Checking", "for"]));
Running this code will yield:
2
14
StringUtils.indexOfDifference()
The .indexOfDifference()
method compares two character arrays, and returns the index of the first differing character:
String s1 = "Hello World!"
String s2 = "Hello world!"
System.out.println(StringUtils.indexOfDifference(s1, s2));
Running this code will yield:
6
StringUtils.indexOfIgnoreCase()
The .indexOfIgnoreCase()
method will return the index of the first occurrence of a character in a character sequence, ignoring its case:
String string = "Checking for substrings within a String is a fairly common task in programming."
System.out.println(StringUtils.indexOf(string, 'c'));
System.out.println(StringUtils.indexOfIgnoreCase(string, 'c'));
Running this code will yield:
3
0
StringUtils.lastIndexOf()
And finally, the .lastIndexOf()
method works pretty much the same as the regular core Java method:
String string = "Lorem ipsum dolor sit amet.";
// You can also use unicode for characters
System.out.println(StringUtils.lastIndexOf(string, 'i'));
System.out.println(StringUtils.lastIndexOf(string, 'i', 8));
System.out.println(StringUtils.lastIndexOf(string, "dolor"));
System.out.println(StringUtils.lastIndexOf(string, "Lorem", 10));
Running this code will yield:
19
6
12
0
StringUtils.containsIgnoreCase()
The .containsIgnoreCase()
method checks if String contains a substring, ignoring the case:
String string = "Checking for substrings within a String is a fairly common task in programming.";
System.out.println(StringUtils.containsIgnoreCase(string, "cOmMOn tAsK"));
Running this code will yield:
true
StringUtils.containsOnly()
The .containsOnly()
method checks if a character sequence contains only the specifies values.
This can be a bit misleading, so another way to put it is – it checks if the character sequence is made up of only the specified characters. It accepts either a String or a character sequence:
String string = "Hello World!"
System.out.println(StringUtils.containsOnly(string, 'HleWord!'));
System.out.println(StringUtils.containsOnly(string, "wrld"));
Running this will yield:
true
false
The "Hello World!"
String indeed is constructed of only the characters in the 'HleWord!'
sequence.
Note: Not all of the characters from the sequence need to be used in the string
for the method to return true. What matters is that string
doesn’t contain a character that’s not in the character sequence.
StringUtils.containsNone()
The .containsNone()
method checks if the String contains any of the “forbidden” characters from a set. If it does, false
is returned, and vice-versa:
String string = "Hello World!"
System.out.println(StringUtils.containsNone(string, 'xmt'));
System.out.println(StringUtils.containsNone(string, "wrld"));
Running this code yields:
true
false
StringUtils.containsAny()
And finally, the .containsAny()
method returns true
if a character sequence contains any of the passed parameters in the form of a character sequence or a String:
String string = "Hello World!"
System.out.println(StringUtils.containsAny(string, ['h', 'm']));
System.out.println(StringUtils.containsAny(string, "hell"));
This code would yield:
true
true
Conclusion
In conclusion, there are many ways to check for a substring in a String. The core Java approach will be enough in most cases, though if you need to check with more than a single condition – Apache Commons is a real time-saver.
In many cases, defining logic of your own for a method such as .indexOfAnyBut()
would be a pain and simply redundant. Since most projects nowadays already have Apache Commons in the classpath, it’s most likely that you can simply use the methods provided by the StringUtils
class.