Hoe haal je getallen uit een string en krijg je een array van ints?

Ik heb een String-variabele (eigenlijk een Engelse zin met een niet-gespecificeerd aantal getallen) en ik wil alle getallen extraheren in een array van gehele getallen. Ik vroeg me af of er een snelle oplossing was met reguliere expressies?


Ik heb de oplossing van Sean gebruikt en deze iets gewijzigd:

LinkedList<String> numbers = new LinkedList<String>();
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(line); 
while (m.find()) {
   numbers.add(m.group());
}

Antwoord 1, autoriteit 100%

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

… drukt -2en 12af.


-? komt overeen met een leidend minteken — optioneel. \d komt overeen met een cijfer, en we moeten echter \schrijven als \\in een Java String. Dus \d+ komt overeen met 1 of meer cijfers.


Antwoord 2, autoriteit 30%

Hoe zit het met het gebruik van replaceAlljava.lang.String methode:

   String str = "qwerty-1qwerty-2 455 f0gfg 4";      
    str = str.replaceAll("[^-?0-9]+", " "); 
    System.out.println(Arrays.asList(str.trim().split(" ")));

Uitvoer:

[-1, -2, 455, 0, 4]

Beschrijving

[^-?0-9]+
  • [en ]bakenen een reeks tekens af om enkelvoudig te matchen, d.w.z. slechts één keer in willekeurige volgorde
  • ^Speciale identifier gebruikt aan het begin van de set, gebruikt om aan te geven dat alle tekens die nietaanwezig zijn in de set met scheidingstekens, overeenkomen met alle tekens die aanwezig zijn in de set .
  • +Tussen één en onbeperkte keren, zo vaak mogelijk, teruggeven als dat nodig is
  • -?Een van de tekens “-” en “?”
  • 0-9Een teken in het bereik tussen “0” en “9”

Antwoord 3, autoriteit 10%

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

Je kunt [0-9] eigenlijk vervangen door \d, maar dat vereist dubbele backslash-escaping, waardoor het moeilijker te lezen is.


Antwoord 4, autoriteit 5%

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

Dit is voor het extraheren van getallen met behoud van de komma


Antwoord 5, autoriteit 4%

Het geaccepteerde antwoord detecteert cijfers maar detecteert geen geformatteerde getallen, b.v. 2.000, noch decimalen, b.v. 4.8. Gebruik hiervoor -?\\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);

Uitvoer:
[4.8, 2,000]


Antwoord 6, autoriteit 2%

gebruik voor rationale getallen deze: (([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))


Antwoord 7, autoriteit 2%

Met Java 8 kunt u het volgende doen:

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]

Als u geen negatieve getallen heeft, kunt u de replaceAllverwijderen (en !s.isEmpty()gebruiken in filter), aangezien dat alleen is om iets als 2-34correct te splitsen (dit kan ook puur met regex worden afgehandeld in split, maar het is vrij ingewikkeld).

Arrays.streamverandert onze String[]in een Stream<String>.

filterverwijdert de voor- en achterliggende lege tekenreeksen en alle -die geen deel uitmaken van een getal.

mapToInt(Integer::parseInt).toArray()roept parseIntaan op elke Stringom ons een int[].


Als alternatief heeft Java 9 een Matcher.resultsmethode, die het volgende mogelijk zou moeten maken:

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]

Zoals het er nu uitziet, is geen van beide een grote verbetering ten opzichte van het doorlopen van de resultaten met Pattern/ Matcherzoals weergegeven in de andere antwoorden, maar het zou eenvoudiger moeten zijn als je dit wilt opvolgen met complexere operaties die aanzienlijk worden vereenvoudigd door het gebruik van streams.


Antwoord 8

Haal hiermee alle reële getallen op.

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

Antwoord 9

Fractietekens en groeperingstekens voor het representeren van reële getallen kunnen per taal verschillen. Hetzelfde reële getal kan op zeer verschillende manieren worden geschreven, afhankelijk van de taal.

De nummer twee miljoen in het Duits

2.000.0000,00

en in het Engels

2.000.000,00

Een methode om reële getallen volledig uit een gegeven string te extraheren op een taalonafhankelijke manier:

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

Antwoord 10

Als je getallen wilt uitsluiten die in woorden voorkomen, zoals bar1 of aa1bb, voeg dan woordgrenzen \b toe aan een van de op regex gebaseerde antwoorden. Bijvoorbeeld:

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

toont:

2
12

Antwoord 11

Ik raad aan om de ASCII-waarden te controleren om getallen uit een string te halen
Stel dat je een invoerreeks hebt als mijnnaam12345en als je gewoon de getallen 12345wilt extraheren, kun je dit doen door eerst de tekenreeks te converteren naar Character Arraygebruik dan de volgende pseudocode

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

zodra de getallen zijn geëxtraheerd, voeg ze toe aan een array

Hopelijk helpt dit


Antwoord 12

Ik vond deze uitdrukking het eenvoudigst

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

Antwoord 13

public static String extractNumberFromString(String number) {
    String num = number.replaceAll("[^0-9]+", " ");
    return num.replaceAll(" ", "");
}

extraheert alleen getallen uit string

Other episodes