簡體   English   中英

使用正則表達式屏蔽信用卡號

[英]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 位數字和可選連字符
  • $字符串結尾
  • )關閉前瞻

正則表達式演示| Java演示

示例代碼

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("(?<!^..).(?=.*...)", "*")); 

請參閱Java 演示正則表達式演示

正則表達式詳細信息

  • (?<=.{3}|^.{0,1}) - 必須有任何三個字符,而不是緊鄰當前位置左側的換行符,或字符串的開頭,或開頭的單個字符字符串的
  • (?<.^..) - 如果在當前位置左側緊鄰除換行符之外的任何兩個字符,則匹配失敗
  • . - 除換行符以外的任何字符
  • (?=.*...) - 當前位置右側必須有除換行符以外的任意三個字符。

如果 CC 號碼總是有 16 位數字,如示例中那樣,並且如 Visa 和 MasterCard CC 一樣,則可以用星號替換以下正則表達式的匹配項。

\d(?!\d{0,2}$|\d{13}$)

啟動你的引擎!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM