Как извлечь числа из строки и получить массив ints?


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


я использовал решение Шона и немного изменил его:

LinkedList<String> numbers = new LinkedList<String>();

Pattern p = Pattern.compile("d+");
Matcher m = p.matcher(line); 
while (m.find()) {
   numbers.add(m.group());
}
10 91

10 ответов:

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. Итак, \d + соответствует 1 или более цифр.

как насчет того, чтобы использовать replaceAll java.ленг.Строковый метод:

    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"
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, но это включает в себя двойной обратный Слэш, что затрудняет чтение.

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

Это для извлечения чисел с сохранением десятичной

для рациональных чисел используйте это:(([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))

принятый ответ обнаруживает цифры, но не обнаруживает сформированные числа, например 2,000, ни десятичные знаки, например 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]

используете 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.результаты метод, который должен учитывать что-то вроде:

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 как показано в другие ответы, но это должно быть проще, если вы хотите следить за этим с более сложные операции, которые значительно упрощаются с использованием потоков.

Я бы предложил проверить значения ASCII для извлечения чисел из строки Предположим, у вас есть входная строка как myname12345 а если вы хотите просто извлечь числа 12345 вы можете сделать это путем преобразования строки Массив Символов затем используйте следующие psuedocode

for(int i=0;i<CharacterArray.length;i++)
    {
  if(a[i]>=48&&a[i]<=58)
          System.out.print(a[i]);
    }

после извлечения чисел добавьте их в массив

надеюсь, что это помогает

Я нашел это выражение простейшей

String[] extractednums = msg.split("\\D++");

извлечь все действительные числа, используя это.

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