Есть ли способ узнать, сколько чисел находится в конце строки, не зная точного индекса?

#java #string #substring

#java #строка #подстрока

Вопрос:

У меня есть метод, который извлекает определенную подстроку из строки. Эта подстрока состоит из чисел в строке. Затем это анализируется до целого числа.

Метод:

 protected int startIndex() throws Exception {
    String str = getWorkBook().getDefinedName("XYZ");
    String sStr = str.substring(10,13);

    return Integer.parseInt(sStr) - 1;
}
 

Пример:

Строка :

‘0 DB’! $ B $ 460

Подстрока :

460

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

Мой подход:

 String str = getWorkBook().getDefinedName("XYZ");
int length = str.length();
String sStr = str.substring(length - 3, length);
 

Это хорошо работает для этого примера.

Теперь проблема в том, что числа в конце строки также могут состоять из 4 или 5 цифр. Если это так, я, естественно, получаю NullPointerException .

Есть ли способ или другой подход, чтобы узнать, сколько чисел находится в конце строки?

Ответ №1:

Вы можете использовать регулярное выражение, (?<=D)d $ которое означает одну или несколько цифр (т.Е. d ) с конца строки, которым предшествуют не цифры (т.Е. D ).

 import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getNumber("'0 DB'!$B$460"));
    }

    static String getNumber(String str) {
        Matcher matcher = Pattern.compile("(?<=\D)\d $").matcher(str);
        if (matcher.find()) {
            return matcher.group();
        }

        // If no match is found, return the string itself
        return str;
    }
}
 

Ответ №2:

В вашем случае я бы рекомендовал использовать регулярное выражение с replaceAll следующим образом:

 String sStr = str.replaceAll(".*?([0-9] )$", "$1");
 

Это извлечет все цифры в конце или вашу строку или любую длину.

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

 String sStr = str.replaceAll(".*?([0-9] )$", "$1");
if (!sStr.isEmpty()) {
    return Integer.parseInt(sStr) - 1;    
}
return 0; // or any default value
 

Комментарии:

1. регулярное выражение да, но replaceAll может применять регулярное выражение несколько раз к строке поиска (если присутствует несколько (блоков) чисел, и в конце все числа будут объединены в один большой числовой блок.

2. @Robert честно говоря, я вас не понимаю, не могли бы вы объяснить на примере, пожалуйста!

3. Посмотрите на пример ввода '0 DB'!$B$460 в вопросе. Ваш код возвращает 0460 вместо 460 . В этом случае, поскольку первое число является a 0 , анализируемое число будет таким же, но если есть число (числа), отличное от 0, ваш код завершается с ошибкой.

4. @Robert правильно, я пропустил добавление $ в регулярное .*?([0-9] )$ выражение, исправьте это.

5. Так что это работает нормально. Спасибо за этот новый подход.

Ответ №3:

Если вы просто хотите получить последнее число, вы можете просмотреть всю строку при возврате и получить начальный индекс:

 protected static int startIndex() {
    String str = getWorkBook().getDefinedName("XYZ");

    if(Character.isDigit(str.charAt(str.length() - 1))) {
        for(int i = str.length() - 1; i >= 0; i--){
            if(!Character.isDigit(str.charAt(i)))
                return i 1;
        }
    }
    return -1;
}
 

а затем распечатать его:

 public static void main(String[] args)  {
    int start = startIndex();
    if(start != -1)
       System.out.println(getWorkBook().getDefinedName("XYZ").substring(start));
   else 
      System.out.println("No Number found");
}
 

Вам нужно будет добавить

Ответ №4:

Простое и быстрое решение без регулярных выражений:

 public class Main
{
    public static int getLastNumber(String str) {
        int index = str.length() - 1;
        while (index > 0 amp;amp; Character.isDigit(str.charAt(index)))
            index--;
            
        return Integer.parseInt(str.substring(index   1));        
    }
    
    public static void main(String[] args) {
        final String text = "'0 DB'!$B$460";
        System.out.println(getLastNumber(text));
    }
}
 

Вывод будет:

 460
 

Ответ №5:

Если бы я собирался это сделать, я просто искал с конца. Это довольно эффективно. Возвращает -1, если положительное число не найдено. OptionalInt Также могут быть использованы другие варианты возврата и использование an .

 String s = "'0 DB'!$B$460";
int i;
for (i = s.length(); i > 0 amp;amp; Character.isDigit(s.charAt(i-1)); i--);
int vv = (i < s.length()) ? Integer.valueOf(s.substring(i)) : -1;
System.out.println(vv);
 

С принтами

 460
 

Если вы знаете, что в конце всегда будет число, вы можете забыть о троичном (?:) выше и просто выполните следующее:

 int vv = Integer.valueOf(s.substring(i));