Java: проверьте, начинается ли строка с другой строки

Введение В этой статье мы рассмотрим, как проверить, начинается ли строка с другой строки в Java. Это довольно распространенная задача в программировании, которая очень похожа на проверку того, содержит ли строка подстроку [/ java-check-if-string-contains-a-substring /]. Например, это может пригодиться, если мы хотим отфильтровать все слова из огромной выборки, начиная с определенной строки. Однако эта проблема отличается от проверки того, содержит ли строка только определенную подстроку.

Вступление

В этой статье мы рассмотрим, как проверить, начинается ли строка с другой строки в Java .

Это довольно распространенная задача в программировании, которая очень похожа на проверку того, содержит ли строка подстроку . Например, это может пригодиться, если мы хотим отфильтровать все слова из огромной выборки, начиная с определенной строки.

Однако эта проблема отличается от проверки того, содержит ли строка только определенную подстроку, и есть несколько способов сделать это как в Core Java, так и в Apache Commons :

Ядро Java

Начнем с решений, которые можно легко реализовать с помощью Core Java.

String.startsWith ()

Этот метод делает именно то, что нам нужно, и является наиболее распространенным способом решения этой проблемы. Он возвращает boolean , которое указывает, начинается ли строка с предоставленного ключевого слова:

 String string = "every end is a new beginning"; 
 
 System.out.println(string.toLowerCase().startsWith("new".toLowerCase())); 
 System.out.println(string.toLowerCase().startsWith("EVERY".toLowerCase())); 
 System.out.println(string.toLowerCase().startsWith("")); 

Запуск этих выходов:

 false 
 true 
 true 

Примечание. Если переданный параметр является пустой строкой, результат всегда будет true .

Конечно, этот метод чувствителен к регистру и всегда должен использоваться в паре с toLowerCase() или toUpperCase() когда мы просто ищем конкретное ключевое слово и не заботимся о том, совпадают ли регистры.

Stream.anyMatch ()

Еще мы могли бы проверить, начинается ли строка с нескольких подстрок. Скажем, у нас есть несколько стандартизованных префиксов - мы можем использовать make Stream из подстрок и запустить anyMatch() для строки, которую мы проверяем.

Давайте посмотрим, как это сделать:

 String string = "every end is a new beginning"; 
 System.out.println(Stream.of("every", "none").anyMatch(string::startsWith)); 

Здесь мы создали Stream возможных подстрок и проверили, присутствует ли какая-либо из них в начале данной строки, с помощью вызова ссылки на метод для startsWith() .

Этот код приводит к:

 true 

String.indexOf ()

Метод indexOf() может быть весьма полезен при решении множества проблем, связанных с подстроками, включая проверку того, начинается ли строка с определенной.

Метод возвращает индекс первого вхождения подстроки в строке, если она найдена, в противном случае -1 .

У него есть несколько перегруженных вариантов, из которых нам понадобится только один ниже, поскольку у других есть другие устройства:

 public int indexOf(String str) 

Если метод indexOf() возвращает 0 , это означает, что наша строка начинается с другой, которую мы указали в качестве параметра.

Например:

 String string = "Just a sample String"; 
 
 System.out.println(string.toLowerCase().indexOf("just".toLowerCase())); 
 System.out.println(string.toLowerCase().indexOf("String".toLowerCase())); 
 System.out.println(string.toLowerCase().indexOf("something else".toLowerCase())); 

выведет:

 0 
 14 
 -1 
  • Ответ, который мы ищем, находится в нашем первом примере, поскольку он вернул 0 - именно то, что нам нужно, то есть наша строка начинается с заданного параметра.
  • Мы можем ясно видеть, что во втором примере "String" действительно находится в нашей String, но в позиции 14 , а это не то, что мы искали.
  • Третий пример даже не содержится в нашей String и возвращает -1 .

Используя информацию выше, мы можем накапливать логику в функции:

 public static boolean startsWithSubstring(String text, String keyword) { 
 return text.toLowerCase().indexOf(keyword.toLowerCase()) == 0; 
 } 

Шаблон с регулярным выражением и сопоставлением

Класс Pattern - это скомпилированное представление регулярного выражения. С помощью этого Pattern мы можем затем сгенерировать движок, который распознает указанное регулярное выражение - мы можем сгенерировать Matcher .

Мы будем использовать метод find() в сочетании с start() чтобы проверить, Matcher с заданной String:

 public static boolean startsWithSubstring(String text, String keyword) { 
 String inputString = text.toLowerCase(); 
 String subString = keyword.toLowerCase(); 
 
 
 // We compile the regular expression to generate a Pattern object 
 Pattern pattern = Pattern.compile(subString); 
 
 // Then we generate an engine (Matcher) which can be used 
 // to recognize and match the regular expression it was 
 // generated from (in our case "this"). 
 Matcher matcher = pattern.matcher(inputString); 
 
 // find() compares the assigned and compiled patterns, and will return a boolean value indicating if they match. 
 // That's where the start() method comes into play; it returns the index of the position 
 // where the two strings matched, or -1 if it's not found. 
 if (matcher.find()) { 
 return matcher.start() == 0; 
 } 
 return false; 
 } 

Давайте протестируем этот метод:

 System.out.println(startsWithSubstring(string, "every")); 

Это приводит к:

 true 

Использование цикла for

Более низкоуровневым способом решения этой проблемы было бы использование цикла for.

Мы перебираем всю длину строки поиска, сравниваем первые searchString.length() и возвращаем true если все совпадают.

Посмотрим, как все это работает в коде:

 public static boolean startsWithSubstring(String text, String keyword) { 
 for (int i = 0; i < keyword.length(); i++) { 
 if (text.toLowerCase().charAt(i) != keyword.toLowerCase().charAt(i)) { 
 System.out.println("String doesn't start with " + "\"" + keyword + "\""); 
 return false; 
 } else if (i == keyword.length() - 1) { 
 System.out.println("String starts with " + "\"" + keyword + "\""); 
 return true; 
 } 
 } 
 return false; 
 } 

Давайте протестируем этот метод:

 String string = "Just a sample String"; 
 
 System.out.println(startsWithSubstring(string, "just")); 
 System.out.println(startsWithSubstring(string, "String")); 
 System.out.println(startsWithSubstring(string, "something else")); 

Это приводит к:

 String starts with "just" 
 true 
 String doesn't start with "String" 
 false 
 String doesn't start with "something else" 
 false 

По умолчанию, если бы мы не использовали toLowerCase() для выравнивания букв в самом методе, этот подход был бы чувствителен к регистру .

Apache Commons

Библиотека Apache Commons предоставляет функциональные возможности, расширяющие базовую платформу Java Framework. Это одна из лучших сторонних библиотек, которая присутствует во многих современных Java-проектах.

Apache Commons предлагает StringUtils , который содержит множество методов, используемых для управления строками. Большинство из этих методов очень похожи на методы, найденные в java.lang.String . Основное отличие состоит в том, что все методы в классе StringUtils являются нулевыми .

Однако для этой задачи нам понадобится всего несколько методов из этого класса:

  1. .indexOf()
  2. .startsWith()
  3. .startsWithIgnoreCase() .

pom.xml библиотеку Apache Commons в свой проект, добавив зависимость к вашему файлу pom.xml, если вы используете Maven:

 <dependency> 
 <groupId>org.apache.commons</groupId> 
 <artifactId>commons-lang3</artifactId> 
 <version>3.11</version> 
 </dependency> 

Или добавив его в Gradle:

 compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.11' 

StringUtils.indexOf ()

У этого метода есть несколько перегруженных вариантов, каждый из которых возвращает int указывающее индекс первого вхождения подстроки, или -1 если подстрока вообще не появляется.

Мы остановимся на следующем варианте этого метода:

 public static int indexOf(CharSequence seq, CharSequence searchSeq) 

Этот метод принимает два String / CharSequence .

Параметр seq представляет строку, в которой мы будем искать searchSeq . Та же логика , как и раньше - если эта функция возвращает 0 , мы знаем , что наша строка начинается с заданной searchSeq подстроки.

Также имейте в виду, что этот метод, как и его аналог, также чувствителен к регистру , поэтому для достижения нечувствительности к регистру необходимо .toLowerCase() или .toUpperCase()

Использование этого метода очень похоже на использование indexOf() из java.lang.String :

 String string = "a simple string to search in"; 
 
 System.out.println(StringUtils.indexOf(string.toLowerCase(), "a simple".toLowerCase())); 
 System.out.println(StringUtils.indexOf(string.toLowerCase(), "string".toLowerCase())); 
 System.out.println(StringUtils.indexOf(string.toLowerCase(), "something".toLowerCase())); 

Это даст:

 0 
 9 
 -1 

Таким образом, мы можем использовать это как удобный метод:

 public static boolean startsWithSubstring(String text, String keyword) { 
 return StringUtils.indexOf(text.toLowerCase(), keyword.toLowerCase()) == 0; 
 } 

StringUtils.startsWith ()

Этот метод делает именно то, что вы ожидаете. Он также чувствителен к регистру, как и его предшественники, и принимает те же два параметра.

Он возвращает true если text начинается с keyword , или false если нет.

Сравнение двух null значений приведет к true :

 String string = "a simple string to search in"; 
 
 System.out.println(StringUtils.startsWith(string.toLowerCase(), "A SIMPLE")); 
 System.out.println(StringUtils.startsWith(string.toLowerCase(), "A SIMPLE".toLowerCase())); 
 System.out.println(StringUtils.startsWith(null, null)); 

Запуск этого выведет:

 false 
 true 
 true 

StringUtils.startsWithAny ()

startsWithAny() не имеет аналога в java.lang.String и является уникальным для StringUtils .

Однако это очень похоже на то, что мы сделали с anyMatch() в потоке - он проверяет, String с любой из заданных подстрок, возвращая true или false .

Это также чувствительно к регистру:

 String string = "a simple string to search in"; 
 
 System.out.println(StringUtils.startsWithAny(string, "something", "a simple")); 
 System.out.println(StringUtils.startsWithAny(string, "something", "string")); 
 System.out.println(StringUtils.startsWithAny(string, "something", null)); 
 System.out.println(StringUtils.startsWithAny(string, "something", "")); 

Выполнение этого дает нам:

 true 
 false 
 false 
 true 

StringUtils.startsWithIgnoreCase ()

Поскольку вызов toLowerCase() все время в Strings во время сравнения может раздражать, вы также можете подать в суд на startsWithIgnoreCase() .

Как и метод startsWith() из того же класса, он принимает два типа Strings (или CharSequence ), а возвращаемое значение - true или false зависимости от того, действительно ли текст начинается с предоставленного ключевого слова:

 String string = "a simple string to search in"; 
 
 System.out.println(StringUtils.startsWithIgnoreCase(string, "something")); 
 System.out.println(StringUtils.startsWithIgnoreCase(string, "A SIMPLE")); 
 System.out.println(StringUtils.startsWithIgnoreCase(string, "")); 
 System.out.println(StringUtils.startsWithIgnoreCase(string, null)); 

Запуск этих выходов:

 false 
 true 
 true 
 false 

Заключение

В этой статье мы рассмотрели все различные методы проверки того, String с другой String , как в ядре Java, так и с использованием библиотеки Apache Commons.

В заключение, есть много разных способов выполнить эту задачу. На самом деле мы могли бы объединить любой из вышеперечисленных методов, чтобы найти индекс, с которого начинается подстрока, и оттуда проверить, где находится подстрока.

В большинстве случаев для решения этой проблемы достаточно просто использовать методы startsWith() startsWithIgnoreCase() , а также получить наиболее чистый и кратчайший код.

comments powered by Disqus

Содержание