Java正则表达式掩盖列表中的所有元素,最后四个字符可见

问题描述

我有一个如下的字母数字字符串列表

["nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1odeNv","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN"]

我需要屏蔽所有可见的最后4个字符的元素,并且[不得屏蔽以下字符。

["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4y74","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeNv","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX12NN"]

我尝试使用

(\\W+)(\\W+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\W+)(\\W+) 

作为键,$ 1 $ 2XXXXXXXXXX $ 4 $ 5 $ 6 $ 7 $ 8 $ 9作为值

maskedValue = maskedValue.replaceAll("(\\W+)(\\W+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\W+)(\\W+)","$1$2XXXXXXXXXX$4$5$6$7$8$9")

但这只会掩盖第一个元素。

["XXXXXXXXXXdeNv","nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74"]

任何潜在客户均会受到赞赏。预先感谢。

解决方法

对于单个值,您可以使用断言来匹配在字符串末尾断言4个字符的单词字符。

\w(?=\w*\w{4}$)

Regex demo | Java demo

String values[] = {"nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1odeNv","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN"};
for (String element : values)
    System.out.println(element.replaceAll("\\w(?=\\w*\\w{4}$)","X"));

输出

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4y74
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeNv
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX12NN

对于整个字符串,可以在正后方使用有限量词来匹配开头的",后跟多个单词字符。然后匹配在结束"

前有4个字符的所有字符
"(?<=\"{0,100})\\w(?=\\w*\\w{4}\")"

Regex demo | Java demo

String regex = "(?<=\"{0,100})\\w(?=\\w*\\w{4}\")";
String string = "[\"nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74\",\"GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1odeNv\",\"GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN\"] ";
System.out.println(string.replaceAll(regex,"X"));

输出

["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4y74","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeNv","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX12NN"] 
,

使用流:

List<String> terms = Arrays.asList(new String[] {
    "nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN"
});
List<String> termsOut = terms.stream()
    .map(t -> String.join("",Collections.nCopies(t.length() - 4,"x")) +
              t.substring(t.length() - 4))
    .collect(Collectors.toList());
System.out.println(termsOut);

此打印:

[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx4y74,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdeNv,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx12NN]

请注意,此解决方案甚至不使用正则表达式,这意味着它可能胜过基于正则表达式的解决方案。

,

假设每个字符串都以引号开头和结尾

算法:

使用标志或堆栈数据结构来确定它是开始引号还是结束引号。 例如: 遍历字符串。最初,标志将为假。遇到新报价时,您必须翻转标志并继续遍历,直到找到其他报价。您可以使用 堆栈堆栈=新堆栈();

示例工作流程:

String str="random";
    
boolean flag = false;
int idx = 0;
List<Pair<Integer,Integer>> indices = new ArrayList<>();
StringBuilder string = new StringBuilder(); // for final string
int start;
int end;
    
while(idx < str.length()){
    
    if (str.charAt(idx) == '"' && !flag){
    // start index of string
    string.append(s.charAt(idx));
    start = idx;
    flag = true;
    }
    
    else if (str.charAt(idx) == '"' && !flag){
    // end index of string
    flag = false;
    end = idx;
char[] mask = new char[end-3-start];
Arrays.fill(mask,'x');
    string.append(new String(mask)); // need to put 'x' in place
    }
    
    if (!flag){
    string.append(s.charAt(idx));
    }
    
    idx++;
}

复杂度:O(n)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...