Как извлечь числа из строки и получить массив 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