Витяг цифр з рядка на Java


207

У мене об’єкт Java String. Мені потрібно отримати лише цифри. Наведу приклад:

"123-456-789" я хочу "123456789"

Чи існує функція бібліотеки, яка витягує лише цифри?

Дякую за відповіді. Перш ніж спробувати ці дані, я повинен знати, чи потрібно мені встановлювати додаткові бібліотеки?

Відповіді:


546

Ви можете використовувати регулярні вирази та видаляти нецифрові цифри.

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

6
хороший короткий код. Лінійний пошук може бути швидшим, але я думаю, що ваш має більше сенсу.
kasten

18
Я здогадуюсь, що ти можеш зняти все, що хочеш, щоб зняти участь (без сарказму). Але моя особиста думка така: коли великі розробники (а їх у нас тут багато) безкоштовно діляться деякими своїми порадами, то я збираюся вшановувати це, і я лише підкреслюю речі, які справді жахливі (перевірте мій профіль, мій поточний співвідношення 14xx в порівнянні з 17 вниз). Але це моя особиста філософія, і ви вільні мати свою власну.
Шон Патрік Флойд

78
Це не працює, якщо ваш номер має десяткову точку, він також видаляє десяткову точку. str = str.replaceAll("[^\\.0123456789]","");
Аравіндан Р

2
Хоча регекс надзвичайно простий і чистий для перегляду, він страждає від проблем продуктивності, і його слід використовувати лише там, коли у вас є одноразова смужка (як-от подання форми). Якщо ви обробляєте багато даних, це не шлях.
Брілл Паппін

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достатньо. Крім того, ви можете відокремити розподіл StringBuilderз набору нецифрових знаків, записавши окрему функцію, яка приймає CharSequenceяк вхід, а Appendableекземпляр як акумулятор виводу.
seh

1
@seh Звучить цікаво, а не коментувати, чому б не створити власну відповідь за допомогою розширень?
RedYeti

3
@RedYeti Залишити цю відповідь та додати коментар більш почесно, оскільки тоді Шон отримує гроші. Також набагато швидше критикувати чужий код, ніж переписувати його, якщо ви поспішаєте. Не карайте seh за те, що він зробив цінний внесок, він не повинен був додавати ці корисні примхи, і ваша відповідь робить його менш ймовірним зробити це наступного разу.
KomodoDave

2
Я нікого не «караю» - це повне неправильне тлумачення того, що я говорив @seh. Моя думка полягала в тому, що його коментарі додали стільки, що було варте, і насправді так сильно змінилися, що я вважав, що це гарантує відповідь власною. Я впевнений, що Шон Патрік Флойд не переймається тим, що кудо лише допомагає іншим, і він буде абсолютно задоволений тим, що дасть свою відповідь. Я просто заохочував се, оскільки відчув, що його внесок заслуговує більшої наочності. Як можна прочитати мій коментар, як будь-що інше, мене цілком спантеличує, але я прошу вибачення, щоби це якось було.
RedYeti

1
Мені подобається, як ці дискусії піднімаються після того, як деякий час лежали в спокої. Мабуть, найкраще тут зробити для мене - відредагувати відповідь Шона, доповнивши її своїми пропозиціями. Таким чином, Шон продовжить отримувати кредит, якщо відповідь не перейде до статусу вікі спільноти.
seh

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 (див. Документи: download.oracle.com/javase/6/docs/api/java/lang/… )
Шон Патрік Флойд

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визначено наперед.
Дункан Макгрегор

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

Це ігнорує десяткові крапки.

наприклад: якщо у вас є вхід, як 445.3kgбуде вихід 445.3.


У мене "4,5 zi". не працює, тому що він зберігає друге. теж
Marian 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
Шон Патрік Флойд

@seanizer: Тоді це буде краще CharMatcher.inRange ('1', '9'). retainFrom ("123-456-789")
Еміль

@Emil більше схожий на CharMatcher.inRange ('0', '9'), але: так
Шон Патрік Флойд

inRange - це те, що лежить за CharMatcher.DIGIT; pastie.org/1252471 Він просто враховує аттиційні діапазони чисел 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

Я надихнувся кодом Шона Патріка Флойда і трохи переписав його для досягнення максимальної продуктивності.

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) ;
       }
       }
    }
 }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.