ChatGPT解决这个技术问题 Extra ChatGPT

Java String remove all non numeric characters but keep the decimal separator

Trying to remove all letters and characters that are not 0-9 and a period. I'm using Character.isDigit() but it also removes decimal, how can I also keep the decimal?

[myStr = myStr.replaceAll( "[^\\d]", "" )][1] [1]: stackoverflow.com/questions/1533659/…
This is a strange way to say this. Isn't "all letters and characters that are not 0-9 and a period" equivalent to simpler "all characters that are not 0-9 and a period"? I mean, letters are characters which are not 0-9 nor the period.

A
Andriy M

Try this code:

String str = "a12.334tyz.78x";
str = str.replaceAll("[^\\d.]", "");

Now str will contain "12.334.78".


This could also work: > str = str.replaceAll("[\\D.]", "");
@Óscar López: how to include negative numbers also? I mean, I have to replace everything that is not a positive/negative number with an empty space. How to do that?
@PankajSinghal simply include the minus sign in the regex: [^\\d.-]
@yeaaaahhhh..hamfhamf no, that won't work. We have to negate the whole group (including numbers and dots), your suggested code only negates the numbers, and the result won't include dots, as required. Did you test it? using the sample code above, your code returns "1233478", which is incorrect.
Works very well even in Android. Thanks.
P
Peter Lawrey

I would use a regex.

String text = "-jaskdh2367sd.27askjdfh23";
String digits = text.replaceAll("[^0-9.]", "");
System.out.println(digits);

prints

2367.2723

You might like to keep - as well for negative numbers.


You should not escape the dot in your regexp.
Could you please put some explanation for what does ^ and . mean in this statement?
@MansourFahad In a regex [^ means not these characters and inside a [] a . is just a .
Since a . is just a a and doesn’t mean anything, can I just get rid of it?
@MansourFahad only if you want no .s in your result.
S
Sergey Vyacheslavovich Brunov

Solution

With dash

String phoneNumberstr = "Tel: 00971-557890-999";
String numberRefined = phoneNumberstr.replaceAll("[^\\d-]", "");

Result: 0097-557890-999.

Without dash

If you also do not need "-" in String you can do like this:

String phoneNumberstr = "Tel: 00971-55 7890 999";      
String numberRefined = phoneNumberstr.replaceAll("[^0-9]", "");

Result: 0097557890999.


Thanks for the great answe!!r
K
Kerem Baydoğan

With guava:

String input = "abx123.5";
String result = CharMatcher.inRange('0', '9').or(CharMatcher.is('.')).retainFrom(input);

see http://code.google.com/p/guava-libraries/wiki/StringsExplained


@egorikem if your project is already using guava, you can use it at no extra cost..
R
Robert
str = str.replaceAll("\\D+","");

Dunno why people downvoted your solution... Helped me alot, thanks! Votes up!
Thanks Zarial, I see Robert actually edited my answer from str = str.replaceAll("\D+",""); to str = str.replaceAll("\\D+",""); ... So i made this mistake when pasting it into StackO's editor box thingy. So thank you Robert for fixing. Now it works!
it's downvoted cause it's a repost. Exact same answer has already been sublitted 5 years ago !! see above : stackoverflow.com/a/10372905/704246
@SaadBenbouzid huh? what is your definition of the exact same answer?
@SaadBenbouzid 1) that is comment and not an answer 2) that is a completely different regex 3) not all answers which use regex D are identical it's like pointing that all C language answers which use printf() are duplicates. Also if you see an answer in comment you can ask mod to convert it to an answer or even add an answer on your own - answers in comments are discouraged on StackOverlow.
S
Shridutt Kothari

Simple way without using Regex:

Adding an extra character check for dot '.' will solve the requirement:

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) || c == '.') {
            strBuff.append(c);
        }
    }
    return strBuff.toString();
}

Since the StringBuffer is only being used inside the function, and not shared between threads, it would be recommended, for performance reasons, to use StringBuilder, instead. See: stackoverflow.com/a/4793503/679240 and stackoverflow.com/a/2771852/679240
M
Michael

For the Android folks coming here for Kotlin

val dirtyString = "💰 Account Balance: $-12,345.67"
val cleanString = dirtyString.replace("[^\\d.]".toRegex(), "")

Output:

cleanString = "12345.67"

This could then be safely converted toDouble(), toFloat() or toInt() if needed


Or Number , in pure Java.
M
Maher Abuthraa

Currency decimal separator can be different from Locale to another. It could be dangerous to consider . as separator always. i.e.

╔════════════════╦═══════════════════╗
║    Locale      ║      Sample       ║
╠════════════════╬═══════════════════╣
║ USA            ║ $1,222,333.44 USD ║
║ United Kingdom ║ £1.222.333,44 GBP ║
║ European       ║ €1.333.333,44 EUR ║
╚════════════════╩═══════════════════╝

I think the proper way is:

Get decimal character via DecimalFormatSymbols by default Locale or specified one.

Cook regex pattern with decimal character in order to obtain digits only

And here how I am solving it:

code:

import java.text.DecimalFormatSymbols;
import java.util.Locale;

    public static String getDigit(String quote, Locale locale) {
    char decimalSeparator;
    if (locale == null) {
        decimalSeparator = new DecimalFormatSymbols().getDecimalSeparator();
    } else {
        decimalSeparator = new DecimalFormatSymbols(locale).getDecimalSeparator();
    }

    String regex = "[^0-9" + decimalSeparator + "]";
    String valueOnlyDigit = quote.replaceAll(regex, "");
    try {
        return valueOnlyDigit;
    } catch (ArithmeticException | NumberFormatException e) {
        Log.e(TAG, "Error in getMoneyAsDecimal", e);
        return null;
    }
    return null;
}

I hope that may help,'.


Although this was not asked, but this is the only solution that works with localization.
O
Orin

A way to replace it with a java 8 stream:

public static void main(String[] args) throws IOException
{
    String test = "ab19198zxncvl1308j10923.";
    StringBuilder result = new StringBuilder();

    test.chars().mapToObj( i-> (char)i ).filter( c -> Character.isDigit(c) || c == '.' ).forEach( c -> result.append(c) );

    System.out.println( result ); //returns 19198.130810923.
}

Y
Yury

This handles null inputs, negative numbers and decimals (you need to include the Apache Commons Lang library, version 3.8 or higher, in your project):

import org.apache.commons.lang3.RegExUtils;
result = RegExUtils.removeAll(input, "-?[^\\d.]");

Library reference: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/RegExUtils.html


D
David K

The below code should remove all non-digit characters and allow periods.

String newString = currentString.replaceAll("[\\D.]", "");