Masking Email address along with domain using regex - java

The requirement is as below:
Input: rajani#gmail.com
Output: r****i#*****.com
I tried below two regex's but I could not able to mask the gmail(domain name). Kindly help me on this.
String masked_email_Address2=email_Address.replaceAll("(?<=.{1}).(?=[^#]*?.#)", "*");
Output received as r****i#gmail.com
I searched in stack overflow on this, I got the below regex but it does not produce the correct result:
String masked_email_Address1=email_Address.replaceAll("\\b(\\w)[^#]+#\\S+(\\.[^\\s.]+)", "$1***#****$2");
Output received as: r***#****.com -- One star(*) is missed between R&#.

I started out trying to do this with a one-liner using String#replaceAll as you were doing, but then gave up, because variable length lookbehinds are not supported, and I could not come up with a pattern which did not use them.
Instead, try just using a format pattern matcher:
String email = "rajani#gmail.com";
String pattern = "([^#]+)#(.*)\\.(.*)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(email);
if (m.find( )) {
StringBuilder sb = new StringBuilder("");
sb.append(m.group(1).charAt(0));
sb.append(m.group(1).substring(1).replaceAll(".", "*"));
sb.append("#");
sb.append(m.group(2).replaceAll(".", "*"));
sb.append(".").append(m.group(3));
System.out.println(sb);
}
Demo
This may look like a lot of code to do a relatively small formatting job on an email address. If you like, you may put this code into utility method, and then you can still get the masking effect with a single line of code, when you call the method.

How about:
String masked_email_Address2=email_Address.replaceAll("(.)?[^#]*([^#])#\\S+(\\.[^\\s.]+)?", "$1****$2#****$3");
This will work as long as your address is longer than 1 character long.

Try this:
int idx = email_Address.indexOf('#');
String part1 = email_Address.substring(1, idx-1).replaceAll(".", "\\*");
String part2 = email_Address.substring(idx + 1, email_Address.lastIndexOf('.')).replaceAll(".", "\\*");
String masked_email_Address1=email_Address.replaceAll("^(\\S)[^#]+(\\S)#.*(\\..*)", "$1"+ part1 + "$2#" + part2 + "$3");

Related

Java regex pattern overmatching(Pattern matches one sequence instead of two)

When I write: "integralfrom1to10ofx^2)+integralfrom1to10ofx^3)",
I expect my regex:
// INTEGRAL BASIC
Pattern integralFinalPattern = Pattern.compile("integralfrom(.*)to(.*)of(.*)\\)");
Matcher integralFinalMatcher = integralFinalPattern.matcher(regexDedicatedString);
if(integralFinalMatcher.find()){
String integral_user_input = integralFinalMatcher.group(0);
String integral_lower_index = integralFinalMatcher.group(1);
String integral_upper_index = integralFinalMatcher.group(2);
String integral_formula = integralFinalMatcher.group(3);
String ultimateLatexIntegral = "(\\int_{"+ integral_lower_index
+"}^{"+ integral_upper_index +"} " + integral_formula + ")";
mathFormula = mathFormula.replace(integral_user_input, ultimateLatexIntegral);
}
to match these two strings separately, but for now it would interpret it as one.
And in result of it I'd get the following latex SVG:
I would like to have output with two separate integrals, like here:
How can I achieve this with regex?
Obviously, I seek for an idea that would make it work for more than two pieces.
You're doing a lot of work that the Matcher class can do for you. Check it out:
Pattern p = Pattern.compile("integralfrom(?<upper>.*?)to(?<lower>.*?)of(?<formula>.*?)\\)");
Matcher m = p.matcher(subject);
result = m.replaceAll("\\\\int_{${upper}}^{${lower}} (${formula})");
With an input of "integralfrom1to10ofx^2)+integralfrom1to10ofx^3)", the result is:
\int_{1}^{10} (x^2)+\int_{1}^{10} (x^3)

Split a string based on pattern and merge it back

I need to split a string based on a pattern and again i need to merge it back on a portion of string.
for ex: Below is the actual and expected strings.
String actualstr="abc.def.ghi.jkl.mno";
String expectedstr="abc.mno";
When i use below, i can store in a Array and iterate over to get it back. Is there anyway it can be done simple and efficient than below.
String[] splited = actualstr.split("[\\.\\.\\.\\.\\.\\s]+");
Though i can acess the string based on index, is there any other way to do this easily. Please advise.
You do not understand how regexes work.
Here is your regex without the escapes: [\.\.\.\.\.\s]+
You have a character class ([]). Which means there is no reason to have more than one . in it. You also don't need to escape .s in a char class.
Here is an equivalent regex to your regex: [.\s]+. As a Java String that's: "[.\\s]+".
You can do .split("regex") on your string to get an array. It's very simple to get a solution from that point.
I would use a replaceAll in this case
String actualstr="abc.def.ghi.jkl.mno";
String str = actualstr.replaceAll("\\..*\\.", ".");
This will replace everything with the first and last . with a .
You could also use split
String[] parts = actualString.split("\\.");
string str = parts[0]+"."+parts[parts.length-1]; // first and last word
public static String merge(String string, String delimiter, int... partnumbers)
{
String[] parts = string.split(delimiter);
String result = "";
for ( int x = 0 ; x < partnumbers.length ; x ++ )
{
result += result.length() > 0 ? delimiter.replaceAll("\\\\","") : "";
result += parts[partnumbers[x]];
}
return result;
}
and then use it like:
merge("abc.def.ghi.jkl.mno", "\\.", 0, 4);
I would do it this way
Pattern pattern = Pattern.compile("(\\w*\\.).*\\.(\\w*)");
Matcher matcher = pattern.matcher("abc.def.ghi.jkl.mno");
if (matcher.matches()) {
System.out.println(matcher.group(1) + matcher.group(2));
}
If you can cache the result of
Pattern.compile("(\\w*\\.).*\\.(\\w*)")
and reuse "pattern" all over again this code will be very efficient as pattern compilation is the most expensive. java.lang.String.split() method that other answers suggest uses same Pattern.compile() internally if the pattern length is greater then 1. Meaning that it will do this expensive operation of Pattern compilation on each invocation of the method. See java.util.regex - importance of Pattern.compile()?. So it is much better to have the Pattern compiled and cached and reused.
matcher.group(1) refers to the first group of () which is "(\w*\.)"
matcher.group(2) refers to the second one which is "(\w*)"
even though we don't use it here but just to note that group(0) is the match for the whole regex.

How to fix the following RegEx?

I've the following piece of code. I use the Case-insensitve pattern modifier so it will find any occurrence, but what I want is the replacement to be exactly the chars that matched the pattern, keeping the case. How could I fix this?
String str = "Ten tender tEens";
String substr = "te";
str = str.replaceAll("(?i)"+substr, "("+substr+")");
System.out.println( str );
Desired output:
(Te)n (te)nder (tE)ens
Received output:
(te)n (te)nder (te)ens
replaceAll() work as the same ways as matcher(string).replaceAll(exp):
To make this work and for better understanding you can break the code like :
String str = "Ten tender tEens";
Pattern pattern=Pattern.compile("(?i)(te)");
Matcher matcher=pattern.matcher(str);
System.out.println( matcher.replaceAll("$1"));
Combining these steps you can use (does the same):
String substr = "te";
str = str.replaceAll("(?i)("+substr+")", "($1)");
You have to use
str = str.replaceAll("(?i)("+substr+"?)", "($1)");
This will create a group and replace the group.
You need to use capturing group.
str = str.replaceAll("(?i)("+substr+")", "($1)");

Get what was removed by String.replaceAll()

So, let's say I got my regular expression
String regex = "\d*";
for finding any digits.
Now I also got a inputted string, for example
String input = "We got 34 apples and too much to do";
Now I want to replace all digits with "", doing it like that:
input = input.replaceAll(regex, "");
When now printing input I got "We got apples and too much to do". It works, it replaced the 3 and the 4 with "".
Now my question: Is there any way - maybe an existing lib? - to get what actually was replaced?
The example here is very simple, just to understand how it works. Want to use it for complexer inputs and regex.
Thanks for your help.
You can use a Matcher with the append-and-replace procedure:
String regex = "\\d*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
StringBuffer sb = new StringBuffer();
StringBuffer replaced = new StringBuffer();
while(matcher.find()) {
replaced.append(matcher.group());
matcher.appendReplacement(sb, "");
}
matcher.appendTail(sb);
System.out.println(sb.toString()); // prints the replacement result
System.out.println(replaced.toString()); // prints what was replaced

Split string to truncate away the last octet of an IP address

I would like to parse an IP address and get rid of the last octet but I don't know which regular expression to use within Java's String split method.
Example user input: 10.120.10.3
Needed output: 10.120.10
I am thinking something like this but need a way to find and split off after the third dot:
String[] truncated_IP = user_IP.split("\\.");
truncated_IP[0] should contain what I am looking for.
Don't use split(), use lastIndexOf():
input.substring(0, input.lastIndexOf('.'))
Using your example:
String input = "10.120.10.3";
System.out.println(input.substring(0, input.lastIndexOf('.')));
10.120.10
If you really want to use split(), it can be done using the regex \.(?=[^.]+$):
input.split("\\.(?=[^.]+$)")[0]
Again, using your example:
String input = "10.120.10.3";
System.out.println(input.split("\\.(?=[^.]+$)")[0]);
10.120.10
You could use substring and lastIndexOf, like so:
user_IP.substring(0, user_IP.lastIndexOf('.'))
You could write a regex to get you the IPAddress from the string
public void findMe(){
String regex = "(\\d*[.]){2}\\d";
Matcher matcher = Pattern.compile(regex).matcher("192.168.1.123");
if (matcher.find()){
System.out.print(matcher.group());
}
}
Here is a regex pattern than should work. It returns the sub classes too, but the first element should always be the Class C subnet.
var ip = "10.100.243.10";
var classCRegex = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5]).";
var subIP = ip.match(classCRegex)[0];
console.log(subIP);
Result: [10.100.243]
With Split use--
`Code :
String s = "10.11.12.13";
String sPlit[] =s.split("\\.");
for(int i = 0; i < sPlit.length; i++){
System.out.println(sPlit[i]);
}
Output:
10
11
12
13
`
and return a string with all but last.
The IPAddress Java library supports both IPv4 and IPv6 in a polymorphic manner, so it can do this in a more general manner, supporting all potential string formats of IPv4 and IPv6. Disclaimer: I am the project manager of that library.
This example method will truncate the last segment, which is the last octet in IPv4:
static void truncateLastSegment(String str) {
IPAddress addr = new IPAddressString(str).getAddress();
IPAddressSection section = addr.getSection(0, addr.getSegmentCount() - 1);
System.out.println("truncated: " + section);
}
Trying this out on your example as well as an IPv6 example:
truncateLastSegment("10.120.10.3");
truncateLastSegment("2001:db8:0:1234:0:567:8:1");
Output:
truncated: 10.120.10
truncated: 2001:db8:0:1234:0:567:8

Categories