I need a help to use or build a regular expression to mask alphanumeric with *
.
I tried it with this expression, but it doesn't work correctly when it has zeros in the middle of the string:
(?<=[^0].{3})\w+(?=\w{4})
Live samples: https://www.regexplanet.com/share/index.html?share=yyyyf47wp3r
Input | Output |
---|---|
0001113033AA55608981 | 0001113*********8981 |
23456237472347823923 | 2345************3923 |
00000000090000000000 | 0000000009000***0000 |
09008000800060050000 | 09008***********0000 |
AAAABBBBCCCCDDDDEEEE | AAAA************EEEE |
0000BBBBCCCCDDDDEEEE | 0000BBBB********EEEE |
The rules are:
You can capture initial zeros and 3 alhpanumeric chars right after them in one group, the middle part into a second group, and then the last 4 alphanumeric chars into a third group, then only replace each char in the second group.
Here is an example (Java 11 compliant):
String text = "0001113033AA55608981";
Matcher mr = Pattern.compile("^(0*\\w{4})(.*)(\\w{4})$").matcher(text);
text = mr.replaceFirst(m -> m.group(1) + "*".repeat(m.group(2).length()) + m.group(3));
System.out.println(text); // => 0001113**********8981
See the Java demo.
The regex matches
^
- start of string(0*\w{4})
- Group 1: zero or more 0
chars and then any four alphnumeric/underscore chars(.*)
- Group 2: any zero or more chars other than line break chars (replace with \w*
if you only allow "word" chars)(\w{4})
- Group 3: four "word" chars$
- end of string.Java 8 compliant version:
String text = "0001113033AA55608981";
Matcher m = Pattern.compile("^(0*\\w{4})(.*)(\\w{4})$").matcher(text);
StringBuffer result = new StringBuffer();
while (m.find()) {
m.appendReplacement(result, m.group(1) + String.join("", Collections.nCopies(m.group(2).length(), "*")) + m.group(3));
}
m.appendTail(result);
System.out.println(result.toString());
See the Java code demo online.
But you may just use
String text = "0001113033AA55608981";
Matcher m = Pattern.compile("^(0*\\w{4})(.*)(\\w{4})$").matcher(text);
String result = "";
if (m.matches()) {
result = m.group(1) + String.join("", Collections.nCopies(m.group(2).length(), "*")) + m.group(3);
}
System.out.println(result);
No calls to the replace
function. Only a "pure " regex.
(?:^(0*[^0].{3})|\G).(?=.{4,}$)
The regex can be broken down as follows.
(?: group, but do not capture:
----------------------------------------------------------
^ the beginning of a "line"
----------------------------------------------------------
( group and capture to \1:
----------------------------------------------------------
0* '0' (0 or more times (matching
the most amount possible))
----------------------------------------------------------
[^0] any character except '0'
----------------------------------------------------------
.{3} any character except \n (3 times)
----------------------------------------------------------
) end of \1
----------------------------------------------------------
| OR
----------------------------------------------------------
\G where the last m//g left off
----------------------------------------------------------
) end of grouping
----------------------------------------------------------
. any character except \n
----------------------------------------------------------
(?= look ahead to see if there is:
----------------------------------------------------------
.{4,} any character except \n (at least 4
times (matching the most amount
possible))
----------------------------------------------------------
$ before an optional \n, and the end of a
"line"
----------------------------------------------------------
) end of look-ahead
See a Java demo.
import java.util.regex.*;
class Rextester {
public static void main(String[] asd){
final String rx = "(?:^(0*[^0].{3})|\\G).(?=.{4,}$)";
final String text = "0001113033AA55608981\n"
+ "23456237472347823923\n"
+ "00000000090000000000\n"
+ "09008000800060050000\n"
+ "AAAABBBBCCCCDDDDEEEE\n"
+ "0000BBBBCCCCDDDDEEEE\n"
+ "00000000000000000000";
final String subs = "$1*";
final Pattern p = Pattern.compile(rx, Pattern.MULTILINE);
final Matcher m = p.matcher(text);
final String res = m.replaceAll(subs);
System.out.println(res);
}
}
Output.
0001113*********8981
2345************3923
0000000009000***0000
09008***********0000
AAAA************EEEE
0000BBBB********EEEE
00000000000000000000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With