Java에서 문자열에서 숫자 추출


207

Java String객체가 있습니다. 숫자 만 추출해야합니다. 예를 들어 보겠습니다.

"123-456-789" 내가 원하는 "123456789"

숫자 만 추출하는 라이브러리 함수가 있습니까?

답변 주셔서 감사합니다. 시험해보기 전에 추가 llibraries를 설치해야하는지 알아야합니까?

답변:


546

정규식을 사용하고 숫자가 아닌 숫자를 삭제할 수 있습니다.

str = str.replaceAll("\\D+","");

6
좋은 짧은 코드. 선형 검색이 더 빠를 수도 있지만 더 잘 이해할 것입니다.
kasten

18
난 당신이 당신이 downvote 좋아하는 무엇을 downvote 수있는 것 같아요 (비꼬 인 의도하지 않은). 그러나 내 개인적인 의견은 : 위대한 개발자 (그리고 우리가 여기에 많은 사람들이 있음)가 무료로 조언을 공유 할 때, 나는 그것을 존중하게 될 것입니다. 비율은 17에서 14xx로 증가합니다). 그러나 그것은 나의 개인적인 철학이고 당신은 자유롭게 가질 수 있습니다.
Sean Patrick Floyd

78
숫자에 소수점이 있으면 작동하지 않으며 소수점도 제거합니다. str = str.replaceAll("[^\\.0123456789]","");
Aravindan R

2
정규식은보기에 매우 간단하고 깨끗하지만 성능 문제가 발생하며 일회성 스트립 (양식 제출과 같은)이있는 경우에만 사용해야합니다. 많은 양의 데이터를 처리하는 경우에는이 방법이 아닙니다.
Brill Pappin

2
그리고 소수점과 같은 것을 배제해야 할 경우(?!\\.)
azerafati

49

더 자세한 해결책은 다음과 같습니다. 덜 우아하지만 아마도 더 빠를 것입니다.

public static String stripNonDigits(
            final CharSequence input /* inspired by seh's comment */){
    final StringBuilder sb = new StringBuilder(
            input.length() /* also inspired by seh's comment */);
    for(int i = 0; i < input.length(); i++){
        final char c = input.charAt(i);
        if(c > 47 && c < 58){
            sb.append(c);
        }
    }
    return sb.toString();
}

테스트 코드 :

public static void main(final String[] args){
    final String input = "0-123-abc-456-xyz-789";
    final String result = stripNonDigits(input);
    System.out.println(result);
}

산출:

0123456789

BTW : Character.isDigit (ch) 는 0-9를 제외한 많은 다른 문자를 허용하기 때문에 사용하지 않았습니다 .


4
재 할당 할 필요가 없도록 StringBuilder생성자 (예 : 등 input.length())에 크기를 제공 해야합니다. String여기 를 요구할 필요는 없습니다 . CharSequence충분하다. 또한 StringBuildera CharSequence를 입력으로, Appendable인스턴스를 출력 누산기로 받아들이는 별도의 함수를 작성하여 숫자가 아닌 컬렉션에서 할당을 분리 할 수 ​​있습니다 .
seh

1
@seh 흥미롭게 들리지만 확장명을 사용하여 직접 답을 만들지 않는 이유는 무엇입니까?
RedYeti

3
@RedYeti이 답변을 유지하고 의견을 추가하는 것은 Sean이 투표를받은 이후로 더 영광입니다. 서두르면 다른 사람의 코드를 재 작성하는 것보다 다른 사람의 코드를 비판하는 것이 훨씬 빠릅니다. 귀중한 공헌을 한 것에 대해 seh를 처벌하지 말고, 유용한 유용한 음식을 추가 할 필요가 없었으며, 귀하의 응답으로 다음 번에는 그렇게 할 가능성이 줄었습니다.
KomodoDave

2
나는 누군가를 "징벌"하지 않습니다-그것은 내가 @seh에게 말한 것을 완전히 잘못 해석 한 것입니다. 내 요점은 그의 의견이 너무나도 가치가 있었으며 실제로는 너무 많이 바뀌어서 그 자체의 답변이 필요하다고 느꼈다. Sean Patrick Floyd는 다른 사람들을 돕는 것에 만 관심이 없으며 자신의 답변을 제공하는 데 완벽하게 만족할 것입니다. 그의 기여가 더 큰 가시성을 가질 만하다고 느꼈기 때문에 나는 단지 seh를 격려하고 있었다. 다른 어떤 것이든지 완전히 퍼즐로 내 의견을 읽을 수있는 방법은 있지만 어떻게 든하면 seh에 사과드립니다.
RedYeti

1
휴면 상태에서 잠시 동안이 토론이 어떻게 진행되는지 좋아합니다. 아마도 여기서 가장 좋은 일은 Sean의 답변을 편집하여 제안으로 보완하는 것입니다. 이런 식으로 Sean은 답변이 커뮤니티 위키 상태로 전환되지 않는 한 계속 크레딧을받습니다.
seh


21

Google Guava 사용 :

CharMatcher.inRange('0','9').retainFrom("123-456-789")

최신 정보:

사전 계산 된 CharMatcher를 사용 하면 성능을 더욱 향상시킬 수 있습니다

CharMatcher ASCII_DIGITS=CharMatcher.inRange('0','9').precomputed();  
ASCII_DIGITS.retainFrom("123-456-789");

3
이제 Charmatcher.DIGIT사전 정의되었습니다.
Duncan McGregor 11:10에

15
input.replaceAll("[^0-9?!\\.]","")

소수점을 무시합니다.

예를 들면 : 당신은 같은 입력이 있으면 445.3kg출력이됩니다 445.3.


"4.5 zi"가 있습니다. 두 번째를 유지하기 때문에 작동하지 않습니다. 너무
마리아 Klühspies

11

Google Guava 사용 :

CharMatcher.DIGIT.retainFrom("123-456-789");

CharMatcher는 플러그 가능하고 사용하기 매우 흥미 롭습니다. 예를 들어 다음을 수행 할 수 있습니다.

String input = "My phone number is 123-456-789!";
String output = CharMatcher.is('-').or(CharMatcher.DIGIT).retainFrom(input);

출력 == 123-456-789


아주 좋은 해결책 (+1)이지만 다른 것과 같은 문제가 있습니다. 많은 문자가 ASCII 숫자뿐만 아니라 유니 코드 숫자로도 적합합니다. 이 코드는 다음 문자를 모두 유지합니다. unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D
Sean Patrick Floyd

@seanizer : 그러면 이것이 더 나을 것입니다 CharMatcher.inRange ( '1', '9'). retainFrom ( "123-456-789")
Emil

@Emil은 CharMatcher.inRange ( '0', '9')와 비슷하지만 예
Sean Patrick Floyd

inRange는 CharMatcher.DIGIT 뒤에 있습니다. pastie.org/1252471 단순히 attitional UTF 숫자 범위를 고려합니다. 실제로는 숫자로 간주합니다. 실제로는 ASCII 인코딩이 아니기 때문입니다.
BjornS

CharMatcher.JAVA_DIGIT도 같은 목적으로 사용할 수 있습니다. Character.isDigit
BjornS

6

정규식을 사용하여 요구 사항에 맞 춥니 다.

String num,num1,num2;
String str = "123-456-789";
String regex ="(\\d+)";
Matcher matcher = Pattern.compile( regex ).matcher( str);
while (matcher.find( ))
{
num = matcher.group();     
System.out.print(num);                 
}

5

나는 Sean Patrick Floyd 코드에서 영감을 얻었으며 최대 성능을 위해 다시 작성했습니다.

public static String stripNonDigitsV2( CharSequence input ) {
    if (input == null)
        return null;
    if ( input.length() == 0 )
        return "";

    char[] result = new char[input.length()];
    int cursor = 0;
    CharBuffer buffer = CharBuffer.wrap( input );

    while ( buffer.hasRemaining() ) {
        char chr = buffer.get();
        if ( chr > 47 && chr < 58 )
            result[cursor++] = chr;
    }

    return new String( result, 0, cursor );
}

최소한의 숫자로 매우 긴 문자열에 성능 테스트 를 수행 하고 결과는 다음과 같습니다.

  • 원본 코드는 25,5 % 느립니다
  • 구아바 접근이 2.5-3 배 느립니다
  • D +를 사용한 정규 표현식은 3-3.5 배 느립니다.
  • D 만있는 정규 표현식은 25 배 이상 느립니다.

Btw는 해당 문자열의 길이에 따라 다릅니다. 6 개의 숫자 만 포함하는 문자열은 구아바가 50 % 느리고 정규 표현식이 1 배 느립니다.


4
public class FindDigitFromString 
{

    public static void main(String[] args) 
    {
        String s="  Hi How Are You 11  ";        
        String s1=s.replaceAll("[^0-9]+", "");
        //*replacing all the value of string except digit by using "[^0-9]+" regex.*
       System.out.println(s1);          
   }
}

출력 : 11



2

전화 번호 +9 (987) 124124의 코드를 완성했습니다.

유니 코드 문자는 4 바이트를 차지합니다.

public static String stripNonDigitsV2( CharSequence input ) {
    if (input == null)
        return null;
    if ( input.length() == 0 )
        return "";

    char[] result = new char[input.length()];
    int cursor = 0;
    CharBuffer buffer = CharBuffer.wrap( input );
    int i=0;
    while ( i< buffer.length()  ) { //buffer.hasRemaining()
        char chr = buffer.get(i);
        if (chr=='u'){
            i=i+5;
            chr=buffer.get(i);
        }

        if ( chr > 39 && chr < 58 )
            result[cursor++] = chr;
        i=i+1;
    }

    return new String( result, 0, cursor );
}

2

암호:

public class saasa {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String t="123-456-789";
        t=t.replaceAll("-", "");
        System.out.println(t);
    }

0
import java.util.*;
public class FindDigits{

 public static void main(String []args){
    FindDigits h=new  FindDigits();
    h.checkStringIsNumerical();
 }

 void checkStringIsNumerical(){
    String h="hello 123 for the rest of the 98475wt355";
     for(int i=0;i<h.length();i++)  {
      if(h.charAt(i)!=' '){
       System.out.println("Is this '"+h.charAt(i)+"' is a digit?:"+Character.isDigit(h.charAt(i)));
       }
    }
 }

void checkStringIsNumerical2(){
    String h="hello 123 for 2the rest of the 98475wt355";
     for(int i=0;i<h.length();i++)  {
         char chr=h.charAt(i);
      if(chr!=' '){
       if(Character.isDigit(chr)){
          System.out.print(chr) ;
       }
       }
    }
 }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.