Получить Integer с конца строки (переменной длины)

У меня есть строка переменной длины, а в конце строки - некоторые цифры. Что было бы лучшим/эффективным способом, чтобы проанализировать строку и получить число от конца как целое?

Строка и цифры в конце могут быть любой длины. Например:

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

Ответ 1

Что-то по линии:

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);
}

может сделать это.

Это не обязательно "самый эффективный" способ, но если у вас нет критического узкого места вокруг этого кода (как: extract int из миллионов строк), этого должно быть достаточно.

Ответ 2

Другие решения, представленные здесь, являются точными, поэтому я предоставил бы это просто немного другое:

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));
}
  • Он вручную ищет позицию последнего не Character.isDigit(char)
    • Он по-прежнему работает, если ввод - это все цифры
  • Он использует BigInteger, поэтому он может обрабатывать действительно большие числа в конце действительно длинных строк.
    • Используйте Integer.parseInt или Long.parseLong, если суффикс

Ответ 3

Best - такой субъективный термин:-) Если вы не собираетесь делать это совсем немного (в этом случае производительность может иметь приоритет над читабельностью), я бы просто пошел с моим первым чувством кишки:

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

Ответ 4

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;
}

Ответ 5

Я сделаю это без регулярного выражения!

Проверьте мое обновление!

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));
}

Это работает отлично.

Ответ 6

Уже есть много хороших ответов, я просто хотел дать свои два цента.

Я знаю, что запуск parseInt() в цикле не является эффективным способом, но ради простоты.

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;
}

ИСПЫТАНО ПРОТИВ ДРУГИХ ОТВЕТОВ:

Я провел несколько тестов с принятым ответом, и этот код выполняется в 7-10 раз быстрее.

Затем я попытался ответить на второй по популярности ответ, и этот код выполняется в 3-4 раза быстрее.

Ответ 7

Прокрутите каждый символ, ища нечисловые символы. Когда кто-то найден, отрубите его и все до него. После того, как цикл запустил результат, результат в int.

Ответ 8

В целом я предпочитаю чистый и короткий код, но если производительность на самом деле является для вас главным приоритетом, рассмотрите что-то вроде:

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;     
}

Он не использует никаких сложных операций с строкой/регулярным выражением. Но опять же - если производительность не является проблемой, используйте другие методы, представленные выше.

Ответ 9

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;
    }

Ответ 10

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;
}