Reputation: 18639
I have the function which masks credit card numbers in String:
public static String replaceCreditCardNumber(String text){
final String MASKCARD = "$1<MASKED>$2";
final Pattern PATTERNCARD =
Pattern.compile("([0-9]{4})[0-9]{0,9}([0-9]{4})");
Matcher matcher = PATTERNCARD.matcher(text);
if (matcher.find()) {
return matcher.replaceAll(MASKCARD);
}
return text;
}
this function works fine in the following cases:
String text = "Aaaa bbbb aaa=1234567890123456 fdfdfd=aaa";
String expected = "Aaaa bbbb aaa=1234<MASKED>3456 fdfdfd=aaa";
assertEquals(expected,text);//OK
String text = "Aaaa bbbb aaa=\"1234567890123456\" fdfdfd=aaa";
String expected = "Aaaa bbbb aaa=\"1234<MASKED>3456\" fdfdfd=aaa";
assertEquals(expected,text);
However the following case fails
String text = "Aaaa bbbb aaa=1gfg23fgfg4567890123456 fdfdfd=aaa";
String expected = "Aaaa bbbb aaa=1gfg23fgfg4567890123456 fdfdfd=aaa";
assertEquals(expected,text);
I'm getting
aaa=1gfg23fgfg4567[<MASKED>]3456
What am I missing in my regex expression?
Upvotes: 3
Views: 17512
Reputation: 2556
I hope to serve you
I have the following class:
public class PatternCreditCard {
// ------------------------- PATTERN DEFINE TYPE CREDIT --------------------------- //
public static final String VISA = "^4.*";
public static final String VISA_ELECTRON = "^(4026|417500|4508|4844|491(3|7)).*";
public static final String MASTER_CARD = "^5[1-5].*";
public static final String AMEX = "^3[47].*";
public static final String DISCOVER =
"^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65).*";
public static final String DINERS = "^36.*";
public static final String DINERS_CARTE_BLANCHE = "^30[0-5].*";
public static final String JCB = "^35(2[89]|[3-8][0-9]).*";
// ------------------------- PATTERN SEPARATOR GROUP NUMBERS --------------------------- //
public static final String VISA_SEPARATOR =
"^([0-9 ]{5})([0-9 ]{5})?([0-9 ]{5})?(?:([0-9 ]{5})([0-9 ]{5})?([0-9]{5})([0-9]{4}))?$";
public static final String MASTER_CARD_SEPARATOR =
"^([0-9 ]{5})([0-9 ]{5})?([0-9 ]{5})?(?:([0-9 ]{5})([0-9 ]{5})?([0-9]{5})([0-9]{4}))?$";
public static final String AMEX_SEPARATOR =
"^([0-9 ]{5})([ ]?[0-9 ]{7})?(?:([ ]?[0-9 ]{7})([ ]?[0-9]{5}))?$";
public static final String DISCOVER_SEPARATOR =
"^([0-9 ]{5})([0-9 ]{5})?([0-9 ]{5})?(?:([0-9 ]{5})([0-9 ]{5})?([0-9]{5})([0-9]{4}))?$";
// ------------------------- LENGTH PERMITTED FOR CREDIT CARD --------------------------- //
public static final int VISA_LEN = 16;
public static final int MASTER_CARD_LEN = 16;
public static final int AMEX_LEN = 15;
public static final int DISCOVER_LEN = 16;
}
then do a replacement to the String of the credit card number if the return value is "" (empty): means that the String complies with any group in the regular expression.
cardNumber.replaceAll(VISA_SEPARATOR, " ");
Upvotes: 1
Reputation: 785246
You should use word boundaries to make sure to avoid matching unwanted input:
final Pattern PATTERNCARD =
Pattern.compile("\\b([0-9]{4})[0-9]{0,9}([0-9]{4})\\b");
Upvotes: 4
Reputation: 31290
Based on examples:
Pattern.compile("([0-9]{4})[0-9]{8}([0-9]{4})");
Upvotes: 2