web-dev-qa-db-ja.com

文字列から数値を抽出し、intの配列を取得する方法は?

String変数(基本的には指定されていない数の数字を含む英語の文)があり、すべての数字を整数の配列に抽出したいと思います。正規表現で簡単な解決策があるかどうか疑問に思っていましたか?


私はショーンのソリューションを使用し、わずかに変更しました。

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

Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(line); 
while (m.find()) {
   numbers.add(m.group());
}
101
John Manak
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桁以上に一致します。

163
Sean Owen

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」までの範囲の文字
47
Maxim Shoustin
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に置き換えることもできますが、これには二重バックスラッシュのエスケープが含まれ、読みにくくなります。

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

これは、小数を保持する数値を抽出するためのものです

9
Kannan

受け入れられた回答は数字を検出しますが、フォーマットされた数字は検出しません。 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]

5

有理数については、これを使用します:(([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))

4
Andrey

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()は各parseIntStringを呼び出して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を使用して結果をループすることよりも大きな改善ではありませんが、これをさらにフォローアップする場合は、よりシンプルにする必要がありますストリームの使用により大幅に簡素化された複雑な操作。

3
Dukeling

実数を表すための分数とグループ化文字は、言語によって異なる場合があります。同じ実数は、言語に応じて非常に異なる方法で記述できます。

ドイツ語で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;
}
1
AnDus

これを使用してすべての実数を抽出します。

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;
    }
}
1
Swagger 68

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

番号が抽出されたら、配列に追加します

お役に立てれば

1
The_Fresher

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
1
dxl

私はこの表現が最も簡単だとわかりました

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