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 -2
en 12
af.
-? 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 replaceAll
java.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-9
Een 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 replaceAll
verwijderen (en !s.isEmpty()
gebruiken in filter
), aangezien dat alleen is om iets als 2-34
correct te splitsen (dit kan ook puur met regex worden afgehandeld in split
, maar het is vrij ingewikkeld).
Arrays.stream
verandert onze String[]
in een Stream<String>
.
filter
verwijdert de voor- en achterliggende lege tekenreeksen en alle -
die geen deel uitmaken van een getal.
mapToInt(Integer::parseInt).toArray()
roept parseInt
aan op elke String
om 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
/ Matcher
zoals 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