【问题标题】:Java Regex Match and Replace matched group with characters of same lengthJava 正则表达式匹配并用相同长度的字符替换匹配的组
【发布时间】:2018-02-03 17:27:57
【问题描述】:

所以我想匹配信用卡号并以 6*4 格式屏蔽它们。这样只有前 6 个和后 4 个字符可见。之间的字符将是'*'。我试图用 MASK 之类的来弄清楚;

private static final String MASK = "$1***$3";
matcher.replaceAll(MASK);

但无法找到让我在中间返回与组 $2 相同长度的星星的方法。

然后我实现了以下代码并且它可以工作。 但我想问的是是否有更短或更简单的方法来做到这一点。有人知道吗?

private static final String HIDING_MASK = "**********";
private static final String REGEX = "\\b([0-9]{6})([0-9]{3,9})([0-9]{4})\\b";
private static final int groupToReplace = 2;

private String formatMessage(String message) throws NotMatchedException {
    Matcher m = Pattern.compile(REGEX).matcher(message);

    if (!m.find()) throw new NotMatchedException();
    else {
        StringBuilder maskedMessage = new StringBuilder(message);
        do {
            maskedMessage.replace(m.start(groupToReplace), m.end(groupToReplace), 
                    HIDING_MASK.substring(0, (m.end(groupToReplace) - m.start(groupToReplace))));

        } while(m.find(m.end()));

        return maskedMessage.toString();
    }
}

编辑:这是要处理的示例消息。 “2017.08.26 20:51 [Thread-Name] [Class-Name] [MethodName] 信用卡持有人 12345678901234567 02/2022 123 ......”

【问题讨论】:

  • 为什么要为此使用正则表达式? String masked = num.substring(0,6) + "******" + num.substring(12,16)
  • 如果你真的需要正则表达式解决方案,那么看看Pattern#appendReplacement
  • @slim 因为我不知道字符串中有什么以及有多少信用卡号(如果有的话)
  • 啊,等等,你是说用它来查找和替换包含任意文本的长字符串中的数字,其中包含信用卡号码?如果是这样,您应该编辑问题以解释这一点——举一个输入文本示例。

标签: java regex mask


【解决方案1】:
private String formatMessage(String message) throws NotMatchedException { 
    if (message.matches(".*\\b\\d{13,19}\\b.*")) {
        return message.replaceAll("(?:[.\\b]*)(?<=\\d{6})\\d(?=\\d{4})(?:[.\\b]*)", "*");
    } else {
        throw new NotMatchedException() ;
    }
} 

【讨论】:

  • 如果message 仅包含信用卡号作为子字符串,我认为这并不容易。
  • 恐怕你没有理解我的问题。信用卡号并不总是 16 位数字。就我而言,我正在寻找 13 到 19 位数字的卡片。
  • Thx 但我已经实施了类似的方法,正如您在我的问题中看到的那样。我有兴趣以类似于 ALI 的回答的更简单的方式执行此操作。
  • 全部替换也添加到我的答案中
  • 您好,您的回答仍然不是解决方案。我不知道“消息”中的内容。它不包含纯信用卡号。示例消息:“2017.08.26 20:51 [Thread-Name] [Class-Name] [MethodName] Credit card holder 12345678901234567 02/2022 123 .........”等等。因此,我不能像您的回答所建议的那样只检查消息的长度。但无论如何,谢谢。
【解决方案2】:

如果您的文本包含多个可变长度的信用卡号,您可以使用以下内容:

str.replaceAll( "\\b(\\d{13,19})\\b", "\u0000$1\u0000" )
   .replaceAll( "(?<=\\d{6})(?<=\u0000\\d{6,14})\\d(?=\\d{4,12}\u0000)(?=\\d{4})", "*" )
   .replaceAll( "\u0000([\\d*]+)\u0000", "$1" );

虽然不是很可读,但它是一口气完成的。

【讨论】:

    【解决方案3】:

    可读但不酷。

    String in = "1234561231234";
    String mask = in
        .replaceFirst("^\\d{6}(\\d+)\\d{4}$", "$1")
        .replaceAll("\\d", "\\*");
    String out = in
        .replaceFirst("^(\\d{6})\\d+(\\d{4})$", "$1" + mask + "$2");
    

    【讨论】:

      【解决方案4】:

      使用StringBuffer 并覆盖所需的字符:

      StringBuffer buf = new StringBuffer(num);
      for(int i=4; i< buf.length() - 6) {
          buf.setCharAt(i, '*');
      }
      return buf.toString();
      

      你也可以使用buf.replace(int start, int end, String str)

      【讨论】:

        【解决方案5】:

        16 字符“数字”的简单解决方案:

         String masked = num.substring(0,6) + "******" + num.substring(12,16);
        

        对于任意长度的字符串( >10 ):

         String masked = num.substring(0,6) 
                       + stars(num.length() - 10) 
                       + num.substring(num.length() - 6);
        

        ... 其中stars(int n) 返回Stringn 星。见Simple way to repeat a String in java——或者如果你不介意9星的限制,"*********".substring(0,n)

        【讨论】:

          【解决方案6】:

          您只需使用以下代码即可:

          str.replaceAll( "(?<=\\d{6})\\d(?=\\d{4})", "*" );
          

          【讨论】:

          • 按照 OP 的要求执行。它效率低下,但作为交换,您会变得不可读;)
          • 接近但没有。我的最大卡号是 19 位。如果号码大于 19 位,您可以编辑它使其不起作用吗?
          • if(str.length() &lt; 19)?
          • @kerberos84 之前做一个if( str.matches( ".*\\b\\d{13,19}\\b.*" ) )
          • 它仍然匹配 20 位的“12345678901234567890”?
          猜你喜欢
          • 2022-12-01
          • 2013-01-18
          • 1970-01-01
          • 2014-10-22
          • 2021-04-08
          • 1970-01-01
          • 2022-08-10
          • 1970-01-01
          • 2020-07-12
          相关资源
          最近更新 更多