如何删除非数字?

时间:2009-11-06 10:57:48

标签: java

private String removeNonDigits(final String value) {         
   if(value == null || value.isEmpty()){
        return "";
   }
   return value.replaceAll("[^0-9]+", "");
}

有更好的方法吗? Apache的StringUtils是否有类似的方法?

7 个答案:

答案 0 :(得分:8)

为了好玩,我跑了一个基准:

import java.util.List;
import java.util.regex.Pattern;

import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Chars;

public final class Main {
    private static final String INPUT = "0a1b2c3d4e";
    private static final int REPS = 10000000;

    public static volatile String out;

    public static void main(String[] args) {
        System.err.println(removeNonDigits1(INPUT));
        System.err.println(removeNonDigits2(INPUT));
        System.err.println(removeNonDigits3(INPUT));
        System.err.println(removeNonDigits4(INPUT));
        System.err.println(removeNonDigits5(INPUT));

        long t0 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits1(INPUT);
        }
        long t1 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits2(INPUT);
        }
        long t2 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits3(INPUT);
        }
        long t3 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits4(INPUT);
        }
        long t4 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits5(INPUT);
        }
        long t5 = System.currentTimeMillis();
        System.err.printf("removeNonDigits1: %d\n", t1-t0);
        System.err.printf("removeNonDigits2: %d\n", t2-t1);
        System.err.printf("removeNonDigits3: %d\n", t3-t2);
        System.err.printf("removeNonDigits4: %d\n", t4-t3);
        System.err.printf("removeNonDigits5: %d\n", t5-t4);
    }

    private static final String PATTERN_SOURCE = "[^0-9]+";
    private static final Pattern PATTERN = Pattern.compile(PATTERN_SOURCE);

    public static String removeNonDigits1(String input) {
        return input.replaceAll(PATTERN_SOURCE, "");
    }

    public static String removeNonDigits2(String input) {
        return PATTERN.matcher(input).replaceAll("");
    }

    public static String removeNonDigits3(String input) {
        char[] arr = input.toCharArray();
        int j = 0;
        for (int i = 0; i < arr.length; ++ i) {
            if (Character.isDigit(arr[i])) {
                arr[j++] = arr[i];
            }
        }
        return new String(arr, 0, j);
    }

    public static String removeNonDigits4(String input) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < input.length(); ++ i) {
            char c = input.charAt(i);
            if (Character.isDigit(c)) {
                result.append(c);
            }
        }
        return result.toString();
    }

    public static String removeNonDigits5(String input) {
        List<Character> charList = Chars.asList(input.toCharArray());
        Predicate<Character> isDigit =
            new Predicate<Character>() {
                public boolean apply(Character input) {
                    return Character.isDigit(input);
                }
            };
        Iterable<Character> filteredList =
            Iterables.filter(charList, isDigit);
        return Joiner.on("").join(filteredList);
    }
}

得到了这些结果:

removeNonDigits1: 74656
removeNonDigits2: 52235
removeNonDigits3: 4468
removeNonDigits4: 5250
removeNonDigits5: 29610

有趣的部分是removeNonDigits5(Google Collections版本)应该是一个愚蠢,过于复杂和无效的解决方案的例子,但它的速度是正则表达式版本的两倍。

<强>更新: 预编译正则表达式可以提高速度,但不会像人们预期的那样多。

重新使用Matcher会带来另一个轻微的加速,但可能不值得牺牲线程安全性。

答案 1 :(得分:7)

你的方法对我来说似乎很好 - 当你说“更好”时,你正在寻找什么?您的方法在实现中是清晰易懂的,并且具有相当好的性能。

特别是,除非您的应用程序包含在紧密循环中不断调用此方法,否则我认为您不会因为尝试使其更高效而获得任何明显的效果。不要过早优化;首先介绍并优化热点。

答案 2 :(得分:3)

如果这是一个经常被调用的方法,那么可能从编译正则表达式到模式并从每次重用它时获得加速:

private static final Pattern digits = Pattern.compile("[^0-9]");

private String removeNonDigits(final String value) {             
  if(value == null || value.isEmpty()){
    return "";
  }

  return digits.matcher(value).replaceAll("");
}

答案 3 :(得分:1)

另一个版本可能是:

public static String removeNonDigits(final String value) {
    if (value == null || value.isEmpty()) {
        return "";
    }

    StringBuilder sb = new StringBuilder(value.length());
    for (int i = 0; i < value.length(); i++) {
        char c = value.charAt(i);
        if (Character.isDigit(c))
            sb.append(c);
    }
    return sb.toString();
}

答案 4 :(得分:0)

public static String getOnlyNumerics(String str)
{ 
    if (str == null)
    {
       return null;
    }    

    StringBuffer strBuff = new StringBuffer();    
    char c;
    for (int i = 0; i < str.length() ; i++)
    {     
         c = str.charAt(i);              
        if (Character.isDigit(c))
        {  
             strBuff.append(c);       
        }  
    }    

    return strBuff.toString();
}

答案 5 :(得分:0)

只有一个建议: 值。的修剪() .isEmpty() 要么 (0 ==值。的修剪()。长度())

如果你有

   String value="     ";
  • 没有方法trim()

    value == null || value.isEmpty()== false

  • 方法trim()

    value == null || value.isEmpty()== true

第二个在功能上更正确恕我直言

答案 6 :(得分:0)

将我的变种4版本添加到 finnw 上面的乐趣:

    public static String removeNonDigits4a(String input) {
        char[] chars = input.toCharArray();
        int l = chars.length;
        int m = 0;
        char c;
        for (int n = 0; n < l; ) {

            if (Character.isDigit(c = chars[n++])) {
                chars[m++] = c;
            }
        }
        return new String(chars, 0, m);
    }