Dirk Jäckel
Dirk Jäckel

Reputation: 3025

How to format credit card numbers in Java

I want to format a credit card number by grouping the digits seperated by spaces

For example 5112345112345114 Should be formatted as: 5112 3451 1234 5114.

I would like to specify a mask and have the digits rendered into it. For example: "#### #### #### ####" for 16 digits credit card numbers. For Amex (15 digits) It should look like this: "#### ###### #####". If the number is not yet fully available (as it is entered by the card holder) it should render into the mask starting from the left side.

Is there a library or even an API in Java to do this? I looked at java.text.MessageFormat but could not find a way to split up Strings. It seems .net has an API for that: String.Format("{0:0000 0000 0000 0000}", number).

Upvotes: 5

Views: 8074

Answers (3)

chriskrueger
chriskrueger

Reputation: 166

Here is a solution how you can use the format on the TextWatcher. You can change the space index on your own.

class CreditCardFormatWatcher : TextWatcherAdapter() {

    override fun afterTextChanged(s: Editable?) {
        if (s == null || s.isEmpty()) return

        s.forEachIndexed { index, c ->
            val spaceIndex = index == 4 || index == 9 || index == 14
            when {
                !spaceIndex && !c.isDigit()     -> s.delete(index, index + 1)
                spaceIndex && !c.isWhitespace() -> s.insert(index, " ")
            }
        }

        if (s.last().isWhitespace())
            s.delete(s.length - 1, s.length)
    }

}

Upvotes: 0

Filomat
Filomat

Reputation: 833

grouping string by 4 symbols

public static String formatCard(String cardNumber) {
    if (cardNumber == null) return null;
    char delimiter = ' ';
    return cardNumber.replaceAll(".{4}(?!$)", "$0" + delimiter);
}

regexp means: every 4 symbols if it's not end of line

?! is a negative lookahead assertion - it's true if after 4 symbols there is no end of line.

test:

in:  1234567890123456
out: 1234 5678 9012 3456
in:  12345678901234
out: 1234 5678 9012 34

Upvotes: 7

Dmitry Tikhonov
Dmitry Tikhonov

Reputation: 301

You can check the length of a card number and apply an appropriate regexp. For example:

    cardNumber.replaceAll("\\d{4}", "$0 ");
    cardNumber.replaceFirst("\\d{4}", "$0 ").replaceFirst("\\d{6}", "$0 ");

Upvotes: 4

Related Questions