java正则表达式使用可见的最后4个字符屏蔽列表中的所有元素

java正则表达式使用可见的最后4个字符屏蔽列表中的所有元素,java,regex,masking,Java,Regex,Masking,我有一个字母数字字符串列表,如下所示 ["nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1odeNv","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN"] 我需要用可见的最后4个字符屏蔽所有元素,并且不能像下面那样屏蔽[” ["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4y74

我有一个字母数字字符串列表,如下所示

["nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1odeNv","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN"]
我需要用可见的最后4个字符屏蔽所有元素,并且不能像下面那样屏蔽[”

["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4y74","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeNv","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX12NN"]
我试过使用

(\\W+)(\\W+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\W+)(\\W+) 
作为密钥和$1$2xxxxxxxxx$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"]
感谢您提供的任何线索。请提前感谢。

使用流:

List terms=Arrays.asList(新字符串[]){
“nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74”,
“ggqodwqp7ktxxeepyybu5ennp8xpc1odenv”,
“GGQODWQP7KTXXEEPYYEBU5ENNP8XPC1O12NN”
});
List termsOut=terms.stream()
.map(t->String.join(“,Collections.nCopies(t.length()-4,“x”))+
t、 子字符串(t.长度()-4))
.collect(Collectors.toList());
系统输出打印项次(termsOut);
这张照片是:

[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx4y74,
 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxdeNv, 
 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx12NN]

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

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

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

输出

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

对于整个字符串,您可以使用一个正回溯中的有限量词来匹配开头的
,后跟一些单词字符。然后匹配结尾前有4个字符的所有字符


假设每个字符串都以引号开始和结束

算法:

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

工作流示例:

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++;
}
String str=“random”;
布尔标志=假;
int-idx=0;
列表索引=新的ArrayList();
StringBuilder字符串=新的StringBuilder();//用于最终字符串
int启动;
内端;
而(idx

复杂性:O(n)

您可以在字符串
\w(?=\w*\w{4}$)
的末尾匹配一个断言4个单词字符的单词字符,并替换为
X
你好,谢谢您的信息。我已经尝试过了。这里的问题是,上面的正则表达式只匹配一个元素。字符串输入=“[\”ng5wnypvnxs6pbnnbrsk5zang94et6q4y74\”\“GGQODWQP7KTXXEEPYYEBU5ENNP8XPC1ODENV\”,“GGQODWQP7KTXXEEPYYEBU5ENNP8XPC1O12NN\”,“布尔值有效=输入。匹配(\\w(?=\\w*\\w{4}$)”;返回false,因为它与元素列表不匹配。任何答案对您有效吗?如果我必须使用自己的实现屏蔽,则所有提到的建议都有效。在这里,我必须使用第三方定义的方式,只传递一个与我的字符串((\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)匹配的正则表达式键我需要一种类似于下面代码行的方式。maskedValue=maskedValue.replaceAll(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+),“$1$2xxxxxxxxxxxxxx$4$5$6$7$8$9”);整个[“NG5WnebVnYP6PBNbNbNbrsk5Zang946Q4Y74”,“GGQODWQP7KTXXEEPYYEBU5ENNP8XPC1O12NN”]是json响应的一部分,应被视为单个字符串,我只允许使用replaceAll。然后将json数组解析为Java集合。我不理解这个问题。我完全同意您的意见,但我的情况下的屏蔽是通过第三方jar进行的,我应该将属性传递给该jares如下键:\\\“accountIdList\\\”[\\s]*\\:[\\s]*(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)掩码:\\\“accountIdList\\”:$1$2xxxxxxxxxxxxxx$4$5$6$7$8$9第三方jar中的掩码将由这些属性使用java replaceAll方法进行处理。整个[“ng5WnypvnXs6pbnBrsk5zang946Q4Y74”、“ggqoDw7ktyyKey8xPE5xxPc1NvxNvxNvxNvc74”、“NvxPxNxNxNxNxNxNxNxNxNxNxGGQODWQP7KTXXEEPYYEBU5ENNP8XPC1O12NN“]是json响应的一部分,应被视为单个字符串。我不应使用[“元素列表”]标记或拆分此字符串@RamaKrishnaRajuGVSS将其解析为json会更好,但我添加了另一个选项来获取除最后4个字符之外的所有掩码。如果我必须使用自己的实现进行掩码,则所有提到的建议都会起作用。在这里,我必须使用第三方定义的方式,只传递一个与我的字符串(\\W+)(\\W+)(\\W+)(\\W+)(\\W+)匹配的正则表达式(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+))以及它们应该如何屏蔽的格式($1$2xxxxxxxxx$4$5$6$7$8$9)。我需要一种类似于下面代码行的方式。屏蔽值=屏蔽值。替换所有(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+)(\\w+;
String regex = "(?<=\"{0,100})\\w(?=\\w*\\w{4}\")";
String string = "[\"nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74\",\"GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1odeNv\",\"GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN\"] ";
System.out.println(string.replaceAll(regex, "X"));
["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++;
}