Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll explore different ways to find the first occurrence of an integer in a string. For example, given the string “ba31dung123”, we want to find only the first embedded integer, which is 31. We’ll see how to do this with regular expressions and plain Java.

2. Solutions With Regex

Regular expressions (regex) are a powerful tool to match and manipulate strings based on specific patterns. They provide a concise way of specifying a string pattern, and we can use them to search for particular characters, words, or phrases, replace text and validate strings against specific rules.

2.1. Using Matcher and Pattern Classes

The java.util.regex package provides two main classes for pattern matching with regular expressions:

  • Matcher: This class provides methods to perform various matching operations on a string using a given pattern. It’s obtained by calling the matcher() method on a Pattern instance.
  • Pattern: This class represents a compiled regular expression and provides various methods to perform match operations on strings. We create a pattern from a regular expression by calling the compile() method of the Pattern class.

We can utilize them to find the first occurrence of an integer in a string:

@Test
void whenUsingPatternMatcher_findFirstInteger() {
    String str = "ba31dung123";
    Matcher matcher = Pattern.compile("\\d+").matcher(str);
    matcher.find();
    int i = Integer.valueOf(matcher.group());
    Assertions.assertEquals(31, i);
}

We use the expression \\d+ to match one or more consecutive digits.

2.2. Using Scanner

We can also use the java.util.Scanner class. It’s a powerful tool for parsing input data. First, we’ll use its method useDelimiter() to remove all the non-digits. After that, we can extract numbers one by one using the nextInt() method:

@Test
void whenUsingScanner_findFirstInteger() {
    int i = new Scanner("ba31dung123").useDelimiter("\\D+").nextInt();
    Assertions.assertEquals(31, i);
}

The regular expression \\D+ represents all consecutive non-digit characters (the opposite of \\d+).

2.3. Using split()

The split() method in Java is a String class method. It splits a string into substrings based on a specified delimiter and returns an array of the substrings. The delimiter can be a regular expression or a plain string:

@Test
void whenUsingSplit_findFirstInteger() {
    String str = "ba31dung123";
    List<String> tokens = Arrays.stream(str.split("\\D+")).filter(s -> s.length() > 0).collect(Collectors.toList());
    Assertions.assertEquals(31, Integer.parseInt(tokens.get(0)));
}

We used the same regular expression as the earlier. However, this solution can give us an empty array element if the string begins with a delimiter, like in our case. So, to avoid this case, we filtered our list using the Java Stream API and the filter() method.

3. Solution Without Regex

We saw that regex is a great way to solve this problem, but we can do this without them.

Let’s create a method that extracts the first integer from a string:

static Integer findFirstInteger(String s) {
    int i = 0;
    while (i < s.length() && !Character.isDigit(s.charAt(i))) {
        i++;
    }
    int j = i;
    while (j < s.length() && Character.isDigit(s.charAt(j))) {
        j++;
    }
    return Integer.parseInt(s.substring(i, j));
}

We start by iterating through the String until we find the first digit. Then we use the isDigit() method to recognize a digit character. Next, we store the index of the first digit in the i variable. Then, we iterate again until we find our number’s end (equal to the first non-digit character). Then we can return the substring from i to j.

Let’s test our findFirstInteger() method:

@Test
void whenUsingCustomMethod_findFirstInteger() {
    String str = "ba31dung123";
    Integer i = FirstOccurrenceOfAnInteger.findFirstInteger(str);
    Assertions.assertEquals(31, i);
}

4. Conclusion

In this quick article, we explored different alternatives to extract the first embedded integer from a string. We saw that regex has various applications for this task, but we can also do it without it.

As usual, the source for the examples is available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.