black666
black666

Reputation: 3027

Get the Integer from the end of a string (variable length)

I have a string of a variable length and at the end of the string are some digits. What would be the best / efficient way, to parse the string and get the number from the end as an Integer?

The String and the digits at the end can can be of any length. For example:

abcd123 --> 123
abc12345 --> 12345
ab4cd1 --> 1

Upvotes: 20

Views: 19334

Answers (10)

ossobuko
ossobuko

Reputation: 871

There is already many good answers, I just wanted to give my two cents.

I know running parseInt() in a loop is not an efficient way but for sake of simplicity.

public static int getIntFromEnd (String string) {
  for (int a = string.length()-1; a >=0; a--)
  try {
    int result = Integer.parseInt(string.substring(a,string.length()));
    // the whole string is integer
    if(a == 0) return result;
  } catch (Exception e) {
    // there is no numbers at the end
    if(a == string.length()-1) break;
    return Integer.parseInt(string.substring(a+1,string.length()));
  }
  // there is no numbers
  return -1;
}

TESTED AGAINST OTHER ANSWERS:

I have run some tests against the accepted answer, and this code runs 7 to 10 times faster.

Then I tried it against the second most upvoted answer, and this code runs 3 to 4 times faster.

Upvotes: 1

slipset
slipset

Reputation: 3078

private int intAtEnd(String string) {
        int i, j;
        i = j = string.length();
        while (--i > 0) {
            if (Character.isDigit(string.charAt(i))) continue;
            i++;
            break;
        } 
        if (j - i > 1) return Integer.parseInt(string.substring(i));
        return -1;
    }

Upvotes: 1

Mansingh Shitole
Mansingh Shitole

Reputation: 151

public int getIntFromEndOfString(String inpStr){
    int revVal = 0;
    boolean flag = false;
    String reverseNo  = "", result = "";
    for (int i = inpStr.length()-1; i >= 0 ; i--) {
        reverseNo = String.valueOf(inpStr.charAt(i));
        if(!flag)
        if(reverseNo.equals("0") ||reverseNo.equals("1") || reverseNo.equals("2") || reverseNo.equals("3")
                | reverseNo.equals("4") || reverseNo.equals("5") || reverseNo.equals("6") || reverseNo.equals("7")
                || reverseNo.equals("8") || reverseNo.equals("9")){
            revVal = Integer.parseInt(reverseNo);
            result+= String.valueOf(revVal);
        }else{
            inpStr = result;
            i = inpStr.length();
            flag = true;
            result = "";
        }else{
            result += reverseNo;
        }
    }
    revVal = Integer.parseInt(result);
    return revVal;
}

Upvotes: 1

Martijn Courteaux
Martijn Courteaux

Reputation: 68847

I'm going to do this without regex!

Check out my update!

public static int getLastInt(String line)
{
    int offset = line.length();
    for (int i = line.length() - 1; i >= 0; i--)
    {
        char c = line.charAt(i);
        if (Character.isDigit(c))
        {
            offset--;
        }
        else
        {
            if (offset == line.length())
            {
                 // No int at the end
                 return Integer.MIN_VALUE;
            }
            return Integer.parseInt(line.substring(offset));
        }
    }
    return Integer.parseInt(line.substring(offset));
}

This works perfect.

Upvotes: 2

polygenelubricants
polygenelubricants

Reputation: 383726

Other solutions provided here are fine, so I'll provide this one just to be a bit different:

public static BigInteger lastBigInteger(String s) {
    int i = s.length();
    while (i > 0 && Character.isDigit(s.charAt(i - 1))) {
        i--;
    }
    return new BigInteger(s.substring(i));
}
  • It manually looks for the position of the last non-Character.isDigit(char)
    • It still works if the input is all digit
  • It uses BigInteger, so it can handle really large numbers at the end of really long strings.
    • Use Integer.parseInt or Long.parseLong if either sufffice

Upvotes: 17

Matthew T. Staebler
Matthew T. Staebler

Reputation: 4996

int getTrailingInteger(String str)
{
    int positionOfLastDigit = getPositionOfLastDigit(str);
    if (positionOfLastDigit == str.length())
    {
        // string does not end in digits
        return -1;
    }
    return Integer.parseInt(str.substring(positionOfLastDigit));
}

int getPositionOfLastDigit(String str)
{
    int pos;
    for (pos=str.length()-1; pos>=0; --pos)
    {
        char c = str.charAt(pos);
        if (!Character.isDigit(c)) break;
    }
    return pos + 1;
}

Upvotes: 3

VonC
VonC

Reputation: 1323753

Something along the line of:

final static Pattern lastIntPattern = Pattern.compile("[^0-9]+([0-9]+)$");
String input = "...";
Matcher matcher = lastIntPattern.matcher(input);
if (matcher.find()) {
    String someNumberStr = matcher.group(1);
    int lastNumberInt = Integer.parseInt(someNumberStr);
}

could do it.

This isn't necessary the "most efficient" way, but unless you have a critical bottleneck around this code (as: extract int from millions of String), this should be enough.

Upvotes: 24

Eyal Schneider
Eyal Schneider

Reputation: 22446

In general I prefer clear and short code, but if performance is really your first priority here, consider something like:

private static int getNum(String s){
    int res = 0;
    int p = 1;
    int i = s.length()-1;
    while(i >= 0){
        int d = s.charAt(i) - '0';
        if (d>=0 && d<=9)
            res += d * p;
        else
            break;
        i--;
        p *= 10;
    }

    return res;     
}

It doesn't use any complex string/regex operations. But again - if performance is not an issue, please use the other techniques presented above.

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 881293

Best is such a subjective term :-) Unless you're going to being doing this quite a bit (in which case performance may take priority over readability), I'd just go with my first gut feeling:

int n = 0;
try {
    n = Integer.parseInt (str.replaceFirst("^.*\\D",""));
} catch (Exception e) {}

Upvotes: 4

jackkav
jackkav

Reputation: 582

Loop through each character looking for non-numeric characters. When one is found chop it and everything off before it. After the loop has run cast the result to int.

Upvotes: 0

Related Questions