Home > Software engineering >  Find index of last non-numeric character in String
Find index of last non-numeric character in String

Time:11-28

Say I have a String made up of numbers, letters, and symbols,

String foo = "987abc<*(123";

How would I be able to find the index of the first number in the last set of numbers ("1", at index 6) in String foo – and if foo = "123", I would get the index of that first number again ("1", at index 0). (And also have it return index 0 if foo = "")

I'm pretty inexperienced with RegEx-es and search patterns like that, alongside the fact that every way I have tried hasn't worked properly (most of the time causing a StringIndexOutOfBoundsException).

What's a reliable, simple way of finding the index of the start of the last set of numbers in a String?

CodePudding user response:

Note: the '1' is at index 8 in your String.

If you don't want it it not necessary to use RegEx for this.

A method like this should do the job:

public static int findLastNumbersIndex(String s) {
  boolean numberFound = false;
  boolean charBeforeNumberFound = false;

  //start at the end of the String
  int index = s.length() - 1;

  //loop from the back to the front while there are more chars 
  //and no nonDigit is found before a digit
  while (index >= 0 && !charBeforeNumberFound) {
    //when the first number was found, set the boolean flag
    if (!numberFound && Character.isDigit(s.charAt(index))) {
      numberFound = true;
    }

    //when already a number was found and there is any nonDigit stop the execution
    if (numberFound && !Character.isDigit(s.charAt(index))) {
      charBeforeNumberFound = true;
      break;
    }

    index--;
  }
   
  return index   1;
}

The execution for different Strings:

public static void main(String[] args) {
  System.out.println("\"987abc<*123\""   " index of lastNumberSet: "   findLastNumbersIndex("987abc<*123"));
  System.out.println("\"987abc<*123abc\""   " index of lastNumberSet: "   findLastNumbersIndex("987abc<*123abc"));
  System.out.println("\"987abc\""   " index of lastNumberSet: "   findLastNumbersIndex("987abc"));
  System.out.println("\"abc987\""   " index of lastNumberSet: "   findLastNumbersIndex("abc987"));
  System.out.println("\"987\""   " index of lastNumberSet: "   findLastNumbersIndex("987"));
  System.out.println("(Empty String)"   " index of lastNumberSet: "   findLastNumbersIndex(""));
  System.out.println("\"abc\""   " index of lastNumberSet: "   findLastNumbersIndex("abc"));
}

returns this output:

"987abc<*123" index of lastNumberSet: 8
"987abc<*123abc" index of lastNumberSet: 8
"987abc" index of lastNumberSet: 0
"abc987" index of lastNumberSet: 3
"987" index of lastNumberSet: 0
(Empty String) index of lastNumberSet: 0
"abc" index of lastNumberSet: 0

CodePudding user response:

You can get it using Regex named group

public static int indexOfLastNumber(String text) {
    Pattern pattern = Pattern.compile("(\\d )(?!.*\\d)");
    Matcher matcher = pattern.matcher(text);
    return matcher.find() ? matcher.start() : -1;
}

and I used test cases from @csalmhof answer, thanks to him

public static void main(String[] args) {
    System.out.println("\"987abc<*123\""   " index of lastNumberSet: "   indexOfLastNumber("987abc<*123"));
    System.out.println("\"987abc<*123abc\""   " index of lastNumberSet: "   indexOfLastNumber("987abc<*123abc"));
    System.out.println("\"987abc\""   " index of lastNumberSet: "   indexOfLastNumber("987abc"));
    System.out.println("\"abc987\""   " index of lastNumberSet: "   indexOfLastNumber("abc987"));
    System.out.println("\"987\""   " index of lastNumberSet: "   indexOfLastNumber("987"));
    System.out.println("(Empty String)"   " index of lastNumberSet: "   indexOfLastNumber(""));
    System.out.println("\"abc\""   " index of lastNumberSet: "   indexOfLastNumber("abc"));
}

Output, -1 for a text that has no numbers

"987abc<*123" index of lastNumberSet: 8
"987abc<*123abc" index of lastNumberSet: 8
"987abc" index of lastNumberSet: 0
"abc987" index of lastNumberSet: 3
"987" index of lastNumberSet: 0
(Empty String) index of lastNumberSet: -1
"abc" index of lastNumberSet: -1
  • Related