如何在Java中实现前缀数组匹配及指定规则的地址掩码处理?
地址前缀匹配与掩码处理实现方案
需求与问题梳理
- 需求:若地址以
S/O、D/O、W/O、C/O开头,需对前缀后的内容进行掩码:保留前4个字符和后4个字符,中间用*填充(示例:S/O: KANTH MEIPPEN PACHU, N-2345, THAMBULI→S/O: KA******************************BULI) - 问题:Java原生
startsWith方法不支持直接传入字符串数组匹配前缀,希望将前缀配置为单个带分隔符的常量简化代码,同时完成完整的掩码逻辑
优化实现方案
方案1:正则表达式匹配(单常量配置)
利用正则表达式的|分隔符将所有前缀整合为单个常量,通过正则匹配快速定位前缀,提取内容后进行掩码处理,兼容性更强。
import java.util.regex.Matcher; import java.util.regex.Pattern; public class AddressMasking { // 单常量配置所有前缀,^匹配字符串开头,:?\\s*兼容前缀后的冒号/空格 private static final String PREFIX_REGEX = "^(S/O|D/O|W/O|C/O):?\\s*"; public static void main(String[] args) { String address = "S/O: KANTH MEIPPEN PACHU, N-2345, THAMBULI"; System.out.println("原地址:" + address); System.out.println("掩码后地址:" + maskAddress(address)); } public static String maskAddress(String address) { if (address == null || address.isBlank()) { return address; } Matcher matcher = Pattern.compile(PREFIX_REGEX).matcher(address); if (!matcher.find()) { return address; // 不匹配前缀,直接返回原地址 } String content = address.substring(matcher.end()); // 内容长度不足8时无需掩码,避免索引越界 if (content.length() <= 8) { return address; } // 生成掩码并拼接结果 String mask = "*".repeat(content.length() - 8); return address.substring(0, matcher.end()) + content.substring(0, 4) + mask + content.substring(content.length() - 4); } }
方案2:集合匹配(单常量配置)
将前缀配置为逗号分隔的字符串,转换为集合后通过流式操作匹配前缀,逻辑更直观易懂。
import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; public class AddressMasking { // 单常量配置所有前缀,逗号分隔 private static final String PREFIX_STR = "S/O,D/O,W/O,C/O"; private static final Set<String> PREFIX_SET = Arrays.stream(PREFIX_STR.split(",")) .collect(Collectors.toSet()); public static void main(String[] args) { String address = "S/O: KANTH MEIPPEN PACHU, N-2345, THAMBULI"; System.out.println("原地址:" + address); System.out.println("掩码后地址:" + maskAddress(address)); } public static String maskAddress(String address) { if (address == null || address.isBlank()) { return address; } // 找到匹配的前缀 String matchedPrefix = PREFIX_SET.stream() .filter(address::startsWith) .findFirst() .orElse(null); if (matchedPrefix == null) { return address; } // 跳过前缀后的冒号和空格 int contentStartIdx = matchedPrefix.length(); while (contentStartIdx < address.length() && (address.charAt(contentStartIdx) == ':' || address.charAt(contentStartIdx) == ' ')) { contentStartIdx++; } String content = address.substring(contentStartIdx); if (content.length() <= 8) { return address; } String mask = "*".repeat(content.length() - 8); return address.substring(0, contentStartIdx) + content.substring(0, 4) + mask + content.substring(content.length() - 4); } }
关键优化点
- 单常量配置前缀:两种方案都将前缀整合为单个常量,便于维护和修改
- 边界处理:增加了空值、短内容的判断,避免索引越界异常
- 格式兼容:处理了前缀后的冒号、空格等分隔符,适配不同格式的地址
- 掩码生成:使用
String.repeat()(Java 11+)简化掩码生成,低版本可替换为String.join("", Collections.nCopies(length, "*"))
内容的提问来源于stack exchange,提问作者Priyadharshini
相关产品推荐
相关产品推荐

