从Java中的字符串中提取数字


207

我有一个Java String对象。我只需要从中提取数字。我举一个例子:

"123-456-789" 我想要 "123456789"

是否有仅提取数字的库函数?

感谢您的回答。在尝试这些之前,我需要知道是否必须安装任何其他库?

Answers:


545

您可以使用正则表达式并删除非数字。

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

6
不错的短代码。线性搜索可能会更快,但我认为您的搜索更有意义。
卡斯滕

18
我想您可以对任何您喜欢的东西进行否决(无讽刺意味)。但是我的个人看法是:当伟大的开发人员(并且我们在这里有很多)免费分享他们的一些建议时,我将很荣幸地做到这一点,而我只会对确实很糟糕的东西投下赞成票(查看我的个人资料,比率是14xx向上17向下)。但这是我的个人哲学,您可以自由拥有自己的哲学。
肖恩·帕特里克·弗洛伊德

78
如果您的数字有小数点,则此方法将无效,它也会删除小数点。str = str.replaceAll("[^\\.0123456789]","");
Aravindan R 2012年

2
尽管正则表达式看起来非常简单和干净,但是它会遇到性能问题,因此只能在一次性使用的情况下使用(例如表单提交)。如果您要处理大量数据,则不是要走的路。
Brill Pappin

2
并且如果您需要排除任何内容(例如小数点),(?!\\.)
azerafati 2014年

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

顺便说一句:我没有使用Character.isDigit(ch),因为它接受除0-9以外的许多其他字符。


4
您应该为StringBuilder构造函数提供一个大小(例如input.length()),以确保不需要重新分配大小。您不需要在String这里要求;CharSequence足够了。另外,您可以StringBuilder编写一个单独的函数接受a CharSequence作为输入,将Appendable实例作为输出累加器,从而将非数字集合的分配与非数字集合分开。
seh 2010年

1
@seh听起来很有趣,但没有评论为什么不使用扩展名创建自己的答案?
RedYeti 2012年

3
@RedYeti保留此答案并添加评论会更加荣幸,因为那时Sean收到了赞扬。如果您急于要批判别人的代码,也比重写它要快得多。不要惩罚seh做出的宝贵贡献,他不必添加那些有用的花絮,而您的回应使他下次不太可能这样做。
KomodoDave

2
我不是在“惩罚”任何人-这完全是我对@seh所说的误解。我的意思是,他的评论增加了很多,这是值得的,而实际上却发生了很大的变化,以至于我认为它有自己的回答。我敢肯定,肖恩·帕特里克·弗洛伊德(Sean Patrick Floyd)并不关心仅帮助他人的荣誉,并且对提供自己的答案感到非常满意。我只是在鼓励seh,因为我认为他的贡献值得更多关注。像其他任何东西一样,如何读完我的评论完全使我感到困惑,但我对她表示歉意。
RedYeti

1
我喜欢休眠一段时间后如何进行这些讨论。也许对我而言,最好的办法是编辑肖恩的答案,并用我的建议加以补充。这样,除非答案转变为社区Wiki状态,否则Sean将继续获得奖励。
seh 2013年

22
public String extractDigits(String src) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < src.length(); i++) {
        char c = src.charAt(i);
        if (Character.isDigit(c)) {
            builder.append(c);
        }
    }
    return builder.toString();
}

我考虑过自己使用Character.isDigit(),但它也接受一些非0-9的字符(请参阅docs:download.oracle.com/javase/6/docs/api/java/lang/…
Sean Patrick Floyd

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预定义。
邓肯·麦格雷戈


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数字。该代码将保留所有这些字符:unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D
肖恩·帕特里克·弗洛伊德

@seanizer:然后,这样会更好吗CharMatcher.inRange('1','9')。retainFrom(“ 123-456-789”)
Emil 2010年

@Emil更像CharMatcher.inRange('0','9'),但:是
Sean Patrick Floyd 2010年

inRange是CharMatcher.DIGIT的背后;pastie.org/1252471 它仅考虑了修饰UTF编号范围,我仍将它们视为数字,因为实际上它们是数字,而不是ASCII编码。
BjornS

您也可以出于相同的目的使用CharMatcher.JAVA_DIGIT,它将仅接受Character.isDigit
BjornS 2010年

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倍以上

顺便说一句,这取决于该字符串有多长。对于仅包含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的代码。

Unicode字符占用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) ;
       }
       }
    }
 }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.