String変数(基本的には指定されていない数の数字を含む英語の文)があり、すべての数字を整数の配列に抽出したいと思います。正規表現で簡単な解決策があるかどうか疑問に思っていましたか?
私はショーンのソリューションを使用し、わずかに変更しました。
LinkedList<String> numbers = new LinkedList<String>();
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(line);
while (m.find()) {
numbers.add(m.group());
}
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.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]+
[
および]
は、文字のセットを単一の一致、つまり任意の順序で1回だけ一致するように区切ります^
セットの先頭に使用される特別な識別子。セットに存在するすべての文字ではなく、区切りセットに存在するすべての文字notに一致することを示すために使用されます。+
1回から無制限の回数、可能な限り何度でも、必要に応じて還元-?
文字「-」および「?」のいずれか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();
これは、小数を保持する数値を抽出するためのものです
受け入れられた回答は数字を検出しますが、フォーマットされた数字は検出しません。 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]
有理数については、これを使用します:(([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))
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
を取り除くことができます(そしてfilter
で!s.isEmpty()
を使用します)。これは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
を使用して結果をループすることよりも大きな改善ではありませんが、これをさらにフォローアップする場合は、よりシンプルにする必要がありますストリームの使用により大幅に簡素化された複雑な操作。
実数を表すための分数とグループ化文字は、言語によって異なる場合があります。同じ実数は、言語に応じて非常に異なる方法で記述できます。
ドイツ語で200万人
2,000,000.
そして英語で
2.000.000,
言語に依存しない方法で特定の文字列から実数を完全に抽出する方法:
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;
}
これを使用してすべての実数を抽出します。
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;
}
}
ASCII値をチェックして文字列から数値を抽出することをお勧めします入力文字列としてmyname12345があり、単に数値12345を抽出する場合最初に文字列をCharacter Arrayに変換してから、次のpseudocode
for(int i=0; i < CharacterArray.length; i++)
{
if( a[i] >=48 && a[i] <= 58)
System.out.print(a[i]);
}
番号が抽出されたら、配列に追加します
お役に立てれば
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
私はこの表現が最も簡単だとわかりました
String[] extractednums = msg.split("\\\\D++");