문자열에서 숫자를 추출하고 정수 배열을 얻는 방법은 무엇입니까?


109

문자열 변수 (기본적으로 숫자가 지정되지 않은 영어 문장)가 있고 모든 숫자를 정수 배열로 추출하고 싶습니다. 정규 표현식에 대한 빠른 솔루션이 있는지 궁금합니다.


Sean의 솔루션을 사용하고 약간 변경했습니다.

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

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

1
숫자가 공백이나 다른 문자로 둘러싸여 있습니까? 숫자의 형식은 어떻게 지정되며 16 진수, 8 진수, 2 진수, 10 진수입니까?
Buhake Sindi

질문에서 분명하다고 생각했습니다. 숫자가있는 영어 문장입니다. 또한 정수 배열에 대해 이야기하고 있었기 때문에 제가 찾고 있던 것은 정수였습니다.
John Manak 2010 년

답변:


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

... 인쇄 -212.


-? 선행 음수 부호와 일치합니다. \ D는 숫자와 일치, 우리는 쓸 필요 \\\하지만 자바 문자열입니다. 따라서 \ d +는 하나 이상의 숫자와 일치합니다.


4
정규 표현식을 설명하여 답변을 보완 해 주시겠습니까?
OscarRyz

3
-? 선행 음수 부호와 일치합니다. \ d는 숫자와 일치하며 Java 문자열에서 \를 \\로 써야합니다. 그래서, \\ D + 1 개 이상의 숫자와 일치
숀 오웬

7
부동을 지원하기 위해 표현식을 Pattern.compile ( "-? [\\ d \\.] +")으로 변경했습니다. 당신은 확실히 나를 인도합니다, Thx!
jlengrand

이 방법은 숫자를 감지하지만 형식이 지정된 숫자 (예 : 2,000. 그러한 사용을 위해-?\\d+,?\\d+|-?\\d+
Mugoma J. Okomba

단일 쉼표 만 지원하므로 "2,000,000"이 누락됩니다. "2,00"과 같은 문자열도 허용합니다. 쉼표 구분 기호를 지원해야하는 경우 : -?\\d+(,\\d{3})*작동합니다.
Sean Owen

52

replaceAlljava.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]+
  • [그리고 ]하나의 임의의 순서로, 즉, 한 번만 일치하는 문자 집합을 delimites
  • ^집합의 시작 부분에 사용되는 특수 식별자로 집합 에있는 모든 문자 대신 구분 된 집합에 없는 모든 문자를 일치시키는 데 사용됩니다 .
  • + 한 번에서 무제한으로 가능한 한 많이, 필요에 따라 환원
  • -? "-"및 "?"문자 중 하나
  • 0-9 "0"에서 "9"사이의 문자

4
왜 물음표를 유지하고 싶습니까? 또한,이 취급 -것들과 함께 숫자로 그 자체로는, 좋아하는 9-, ---6하고 1-2-3.
Alan Moore

1
가져 오기 라이브러리를 사용하지 않는 아주 좋은 대안;)
Jcc.Sanabria

18
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로 바꿀 수 있지만 이중 백 슬래시 이스케이프가 포함되어 읽기가 더 어렵습니다.


이런. Sean 's는 음수를 처리하므로 개선되었습니다.
sidereal

2
당신이 사용하는 경우 당신이 너무 음수를 처리 할? "- [0-9] +"
cegprakash

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

소수를 유지하는 숫자를 추출하기위한 것입니다.


네거티브를 처리하지 않음
OneCricketeer

5

허용 된 대답은 숫자를 감지하지만 형식이 지정된 숫자 (예 : 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]


1
@JulienS .: 동의하지 않습니다. 이 정규식은 OP가 요청한 것보다 훨씬 많은 작업을 수행하며 잘못되었습니다. (적어도 소수 부분은 선택적인 그룹에 있어야하며 그 안에있는 모든 것이 필요하고 탐욕 (?:\.\d+)?
Alan Moore

당신은 확실히 소수점 자리에 포인트가 있습니다. 그러나 형식이 지정된 숫자를 만나는 것은 매우 일반적입니다.
Julien

@AlanMoore 많은 방문자들이 유사성 / 차이가 다양한 문제를 해결하기 위해 / 다른 방법을 찾고 있으며 제안을 제기하는 것이 도움이됩니다. OP조차 지나치게 단순화되었을 수 있습니다.
Mugoma J. Okomba

4

유리수의 경우 다음을 사용하십시오. (([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))


1
OP는 실수가 아니라 정수라고 말했습니다. 또한 점을 이스케이프하는 것을 잊었으며 이러한 괄호는 필요하지 않습니다.
Alan Moore

3

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.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로 결과를 반복하는 것보다 큰 개선이 아니지만 다음을 사용하여 상당히 단순화 된 더 복잡한 작업을 수행하려는 경우 더 간단해야합니다. 스트림.


1

이것을 사용하여 모든 실수를 추출하십시오.

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

실수를 나타내는 분수 및 그룹화 문자는 언어마다 다를 수 있습니다. 같은 실수는 언어에 따라 매우 다른 방식으로 쓰여질 수 있습니다.

독일어로 2 백만

2,000,000.00

그리고 영어로

2.000.000,00

언어에 구애받지 않는 방식으로 주어진 문자열에서 실수를 완전히 추출하는 방법 :

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

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

문자열에서 숫자를 추출하기 위해 ASCII 값을 확인하는 것이 좋습니다. 입력 문자열이 myname12345 이고 숫자 12345추출 하려는 경우 먼저 문자열을 문자 배열 로 변환 한 다음 다음 의사 코드 를 사용하면됩니다.

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

숫자가 추출되면 배열에 추가

도움이 되었기를 바랍니다


Java 문자열은 유니 코드 / UTF-16 코드 단위의 시퀀스로 계산됩니다. UTF-16의 디자인에 따라 처음 128 개의 문자는 ASCII 인코딩과 동일한 값 (크기가 같지 않음)을 갖습니다. 그 외에도 ASCII를 다루고 있다고 생각하면 오류가 발생합니다.
Tom Blodget 2014 년

0

이 표현이 가장 간단하다는 것을 알았습니다

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

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

문자열에서 숫자 만 추출

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.