Как извлечь числа из строки и получить массив ints?
У меня есть переменная String (в основном английское предложение с неуказанным числом чисел), и я хотел бы извлечь все числа в массив целых чисел. Мне было интересно, было ли быстрое решение с регулярными выражениями?
Я использовал решение Шона и немного изменил его:
LinkedList<String> numbers = new LinkedList<String>();
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(line);
while (m.find()) {
numbers.add(m.group());
}
Ответы
Ответ 1
Pattern p = Pattern.compile("-?\\d+");
Matcher m = p.matcher("There are more than -2 and less than 12 numbers here");
while (m.find()) {
System.out.println(m.group());
}
... печатает -2
и 12
.
-? соответствует ведущему отрицательному знаку - необязательно. \d соответствует цифре, и мы должны писать \
как \\
в Java String. Итак, \d + соответствует 1 или более цифрам.
Ответ 2
Как насчет использования метода replaceAll
java.lang.String:
String str = "qwerty-1qwerty-2 455 f0gfg 4";
str = str.replaceAll("[^-?0-9]+", " ");
System.out.println(Arrays.asList(str.trim().split(" ")));
Выход:
[-1, -2, 455, 0, 4]
Описание
[^-?0-9]+
-
[
и ]
разграничивает набор символов для одинарного совпадения, т.е. только один раз в любом порядке -
^
Специальный идентификатор, используемый в начале набора, используемый для указания соответствия всем символам, отсутствующим в наборе с разделителями, вместо всех символов, присутствующих в наборе. -
+
От одного до неограниченного количества раз, столько раз, сколько возможно, отдача по мере необходимости -
-?
Один из символов "-" и "?" -
0-9
в диапазоне от "0" до "9"
Ответ 3
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher(myString);
while (m.find()) {
int n = Integer.parseInt(m.group());
// append n to list
}
// convert list to array, etc
Фактически вы можете заменить [0-9] на \d, но это связано с двойным обратным слэшем, что затрудняет чтение.
Ответ 4
StringBuffer sBuffer = new StringBuffer();
Pattern p = Pattern.compile("[0-9]+.[0-9]*|[0-9]*.[0-9]+|[0-9]+");
Matcher m = p.matcher(str);
while (m.find()) {
sBuffer.append(m.group());
}
return sBuffer.toString();
Это для извлечения чисел, сохраняющих десятичное число
Ответ 5
Принятый ответ обнаруживает цифры, но не обнаруживает сформированные числа, например. 2000 и десятичные значени, например. 4.8. Для такого использования -?\\d+(,\\d+)*?\\.?\\d+?
:
Pattern p = Pattern.compile("-?\\d+(,\\d+)*?\\.?\\d+?");
List<String> numbers = new ArrayList<String>();
Matcher m = p.matcher("Government has distributed 4.8 million textbooks to 2,000 schools");
while (m.find()) {
numbers.add(m.group());
}
System.out.println(numbers);
Вывод:
[4.8, 2,000]
Ответ 6
для рациональных чисел используйте этот: (([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))
Ответ 7
Используя Java 8, вы можете сделать:
String str = "There 0 are 1 some -2-34 -numbers 567 here 890 .";
int[] ints = Arrays.stream(str.replaceAll("-", " -").split("[^-\\d]+"))
.filter(s -> !s.matches("-?"))
.mapToInt(Integer::parseInt).toArray();
System.out.println(Arrays.toString(ints)); // prints [0, 1, -2, -34, 567, 890]
Если у вас нет отрицательных чисел, вы можете избавиться от replaceAll
(и использовать !s.isEmpty()
в filter
), поскольку это только для правильного разбиения чего-то вроде 2-34
(это также может быть обработано чисто с помощью регулярного выражения в split
, но это довольно сложно).
Arrays.stream
превращает нашу String[]
в Stream<String>
.
filter
избавляет от ведущих и конечных пустых строк, а также от любых -
которые не являются частью числа.
mapToInt(Integer::parseInt).toArray()
вызывает parseInt
для каждой String
чтобы дать нам int[]
.
В качестве альтернативы, в Java 9 есть метод Matcher.results, который должен предусматривать что-то вроде:
Pattern p = Pattern.compile("-?\\d+");
Matcher m = p.matcher("There 0 are 1 some -2-34 -numbers 567 here 890 .");
int[] ints = m.results().map(MatchResults::group).mapToInt(Integer::parseInt).toArray();
System.out.println(Arrays.toString(ints)); // prints [0, 1, -2, -34, 567, 890]
В настоящее время ни один из них не является большим улучшением по сравнению с простым циклическим отображением результатов с помощью Pattern
/Matcher
как показано в других ответах, но это должно быть проще, если вы хотите выполнить более сложные операции, которые значительно упрощаются с помощью использование потоков.
Ответ 8
Я бы предложил проверить значения ASCII для извлечения чисел из строки
Предположим, что у вас есть строка ввода String как myname12345, и если вы хотите просто извлечь номера 12345, вы можете сделать это, сначала преобразуя строку в Массив символов затем используйте следующий psuedocode
for(int i=0;i<CharacterArray.length;i++)
{
if(a[i]>=48&&a[i]<=58)
System.out.print(a[i]);
}
после того, как числа будут извлечены, добавьте их в массив
Надеюсь, что это поможет
Ответ 9
Я нашел это выражение самым простым
String[] extractednums = msg.split("\\\\D++");
Ответ 10
Извлеките все действительные числа, используя это.
public static ArrayList<Double> extractNumbersInOrder(String str){
str+='a';
double[] returnArray = new double[]{};
ArrayList<Double> list = new ArrayList<Double>();
String singleNum="";
Boolean numStarted;
for(char c:str.toCharArray()){
if(isNumber(c)){
singleNum+=c;
} else {
if(!singleNum.equals("")){ //number ended
list.add(Double.valueOf(singleNum));
System.out.println(singleNum);
singleNum="";
}
}
}
return list;
}
public static boolean isNumber(char c){
if(Character.isDigit(c)||c=='-'||c=='+'||c=='.'){
return true;
} else {
return false;
}
}
Ответ 11
Символы дроби и группировки для представления действительных чисел могут отличаться в зависимости от языка. Одно и то же действительное число может быть написано по-разному в зависимости от языка.
Номер два миллиона по-немецки
2,000,000.00
и на английском
2.000.000,00
Метод полного извлечения действительных чисел из заданной строки независимым от языка способом:
public List<BigDecimal> extractDecimals(final String s, final char fraction, final char grouping) {
List<BigDecimal> decimals = new ArrayList<BigDecimal>();
//Remove grouping character for easier regexp extraction
StringBuilder noGrouping = new StringBuilder();
int i = 0;
while(i >= 0 && i < s.length()) {
char c = s.charAt(i);
if(c == grouping) {
int prev = i-1, next = i+1;
boolean isValidGroupingChar =
prev >= 0 && Character.isDigit(s.charAt(prev)) &&
next < s.length() && Character.isDigit(s.charAt(next));
if(!isValidGroupingChar)
noGrouping.append(c);
i++;
} else {
noGrouping.append(c);
i++;
}
}
//the '.' character has to be escaped in regular expressions
String fractionRegex = fraction == POINT ? "\\." : String.valueOf(fraction);
Pattern p = Pattern.compile("-?(\\d+" + fractionRegex + "\\d+|\\d+)");
Matcher m = p.matcher(noGrouping);
while (m.find()) {
String match = m.group().replace(COMMA, POINT);
decimals.add(new BigDecimal(match));
}
return decimals;
}
Ответ 12
Если вы хотите исключить числа, содержащиеся в словах, такие как bar1 или aa1bb, добавьте границы слов \b к любому из ответов на основе регулярных выражений. Например:
Pattern p = Pattern.compile("\\b-?\\d+\\b");
Matcher m = p.matcher("9There 9are more9 th9an -2 and less than 12 numbers here9");
while (m.find()) {
System.out.println(m.group());
}
дисплеи:
2
12