问题描述
我有一个如下的字母数字字符串列表
["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}$)
String values[] = {"nG5wnyPVNxS6PbbDNNbRsK5zanG94Et6Q4y74","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1odeNv","GgQoDWqP7KtxXeePyyebu5EnNp8XxPC1o12NN"};
for (String element : values)
System.out.println(element.replaceAll("\\w(?=\\w*\\w{4}$)","X"));
输出
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4y74
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXdeNv
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX12NN
对于整个字符串,可以在正后方使用有限量词来匹配开头的"
,后跟多个单词字符。然后匹配在结束"
"(?<=\"{0,100})\\w(?=\\w*\\w{4}\")"
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)