#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
. В этом случае, поскольку первое число является a0
, анализируемое число будет таким же, но если есть число (числа), отличное от 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));