[英]Masking credit card number using regex
我試圖掩蓋 CC 號碼,以不掩蓋第三個字符和最后三個字符的方式。
例如.. 7108898787654351
到**0**********351
我試過(?<=.{3}).(?=.*...)
。 它揭示了最后三個字符。 但它也揭示了前三個。
你能就如何單獨揭開第三個角色提出一些建議嗎?
您可以將此正則表達式與前瞻和后視一起使用:
str = str.replaceAll("(?<!^..).(?=.{3})", "*");
//=> **0**********351
正則表達式詳細信息:
(?<.^..)
:否定前瞻斷言我們在開始后沒有 2 個字符(從匹配中排除第 3 個字符).
: 匹配一個字符(?=.{3})
:肯定的前瞻斷言我們至少有 3 個字符我建議正則表達式不是這樣做的唯一方法。
char[] m = new char[16]; // Or whatever length.
Arrays.fill(m, '*');
m[2] = cc.charAt(2);
m[13] = cc.charAt(13);
m[14] = cc.charAt(14);
m[15] = cc.charAt(15);
String masked = new String(m);
它可能更冗長,但它比正則表達式更具可讀性(和可調試性)。
這是另一個正則表達式:
(?!(?:\D*\d){14}$|(?:\D*\d){1,3}$)\d
查看在線演示
這可能看起來有點笨拙,但由於信用卡應該有 16 位數字,我選擇使用負前瞻來查找 x 數量的非數字后跟數字。
(?!
- 負前瞻
(?:
- 打開第一個非捕獲組。
\D*\d
- 匹配零個或多個非數字和一個數字。){14}
- 關閉第一個非捕獲組並匹配 14 次。$
- 結束字符串 ancor。|
- 交替/或。(?:
- 打開第二個非捕獲組。
\D*\d
- 匹配零個或多個非數字和一個數字。){1,3}
- 關閉第二個非捕獲組並將其匹配 1 到 3 次。$
- 結束字符串 ancor。)
- 關閉負前瞻。\d
- 匹配單個數字。現在,這將屏蔽除第三個和最后三個之外的任何數字,無論它們在格式化的 CC 編號中的 position(由於分隔符)如何。
除了前 3 位數字之后的破折號之外,讓第 3 位數字不匹配,並確保字符串末尾始終是 3 位數字:
(?<!^\d{2})\d(?=[\d-]*\d-?\d-?\d$)
解釋
(?<!
Negative lookbehind, assert what is on the left is not
^\d{2}
匹配字符串開頭的 2 位數字)
近距離觀察\d
匹配一個數字(?=
正向前瞻,斷言右邊是
[\d-]*
0+ 次出現-
或數字\d-?\d-?\d
匹配 3 位數字和可選連字符$
字符串結尾)
關閉前瞻示例代碼
String regex = "(?<!^\\d{2})\\d(?=[\\d-]*\\d-?\\d-?\\d$)";
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
String strings[] = { "7108898787654351", "7108-8987-8765-4351"};
for (String s : strings) {
Matcher matcher = pattern.matcher(s);
System.out.println(matcher.replaceAll("*"));
}
Output
**0**********351
**0*-****-****-*351
不要認為你應該使用正則表達式來做你想做的事。 您可以使用StringBuilder
創建所需的字符串
String str = "7108-8987-8765-4351";
StringBuilder sb = new StringBuilder("*".repeat(str.length()));
for (int i = 0; i < str.length(); i++) {
if (i == 2 || i >= str.length() - 3) {
sb.replace(i, i + 1, String.valueOf(str.charAt(i)));
}
}
System.out.print(sb.toString()); // output: **0*************351
您可以添加^.{0,1}
替代項以允許匹配.
當它是字符串中的第一個或第二個字符時:
String s = "7108898787654351"; // **0**********351
System.out.println(s.replaceAll("(?<=.{3}|^.{0,1}).(?=.*...)", "*"));
// => **0**********351
正則表達式也可以寫成符合 PCRE 的模式: (?<=.{3}|^|^.).(?=.*...)
。 正則表達式也可以寫成符合 PCRE 的模式: (?<=.{3}|^|^.).(?=.*...)
。
它等於
System.out.println(s.replaceAll("(?<!^..).(?=.*...)", "*"));
正則表達式詳細信息
(?<=.{3}|^.{0,1})
- 必須有任何三個字符,而不是緊鄰當前位置左側的換行符,或字符串的開頭,或開頭的單個字符字符串的(?<.^..)
- 如果在當前位置左側緊鄰除換行符之外的任何兩個字符,則匹配失敗.
- 除換行符以外的任何字符(?=.*...)
- 當前位置右側必須有除換行符以外的任意三個字符。如果 CC 號碼總是有 16 位數字,如示例中那樣,並且如 Visa 和 MasterCard CC 一樣,則可以用星號替換以下正則表達式的匹配項。
\d(?!\d{0,2}$|\d{13}$)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.