Replace part of substring with specific characters based on delimiter - java

String s = "abc//jason:1234567#123.123.213.212/";
I want to replace all the substring before and after ":" delimiter with "......."
I want my final output to be :
"abc//.....:.......#123.123.213:212/"
I tried doing this since there is a second : in the string it gets messed up, is it there better way to be able to get my output:
String [] headersplit;
headersplit = s.split(":");

If you want to locate only symbols between "//" and "#" then algorithm is simple, provided that mention symbols are compulsory.
public class Main {
public static void main(String[] args) {
String s = "abc//jason:1234567#123.123.213.212/";
System.out.println(replaceSensitiveInfo(s));
}
static String replaceSensitiveInfo(String src) {
int slashes = src.indexOf("//");
int colon = src.indexOf(":", slashes);
int at = src.indexOf("#", colon);
StringBuilder sb = new StringBuilder(src);
sb.replace(slashes + 2, colon, ".".repeat(colon - slashes - 2));
sb.replace(colon + 1, at, ".".repeat(at - colon - 1));
return sb.toString();
}
}

Not the best way but it works for your example and should work for others:
String s = "abc//jason:1234567#123.123.213:212/";
String result = replaceSensitiveInfo(s);
private String replaceSensitiveInfo(String info){
StringBuilder sb = new StringBuilder(info);
String substitute = ".";
int start = sb.indexOf("//") + 2;
int end = sb.indexOf(":");
String firstReplace = substitute.repeat(end - start);
sb.replace(start, end, firstReplace);
int start2 = sb.indexOf(":") + 1;
int end2 = sb.indexOf("#");
String secondReplace = substitute.repeat(end2 - start2);
sb.replace(start2, end2, secondReplace);
return sb.toString();
}

Related

Masking email using java with out regex

I want to mask the email in this format xxx####xx###x####.x##.
x -> to display the character , # -> to hide the character.
For example:
input: testemail#gmail.com,
output: tes##ma###g####.c##
This is the code I have written
private static String maskEmailId(String email, String format) {
int start = format.indexOf("#");
int end = email.indexOf("#");
String result = maskPattern(start, end, email);
start = email.indexOf('#')+ (format.indexOf("#", format.indexOf("#")) - format.indexOf("#") - 1);
end = email.indexOf('.');
result = maskPattern(start + 1, end, result);
start = email.indexOf(".") + (format.indexOf("#", format.indexOf(".")) - format.indexOf(".") - 1);
end = email.length();
result = maskPattern(start + 1, end, result);
return result;
}
private static String maskPattern(int start, int end, String email) {
StringBuilder sb = new StringBuilder(email);
for (int i = start; i < end; i++) {
sb.setCharAt(i, '#');
}
return sb.toString();
}
I am bit confused with the logic if I want to display and hide in between after hiding first time.
Can anyone help on this?

Split String from the last iteration

This post is an update to this one : get specific character in a string with regex and remove unused zero
In the first place, i wanted to remove with an regular expression the unused zero in the last match.
I found that the regular expression is a bit overkill for what i need.
Here is what i would like now,
I would like to use split() method
to get from this :
String myString = "2020-LI50532-3329-00100"
this :
String data1 = "2020"
String data2 = "LI50532"
String data3 = "3329"
String data4 = "00100"
So then i can remove from the LAST data the unused Zero
to convert "00100" in "100"
And then concatenate all the data to get this
"2020-LI50532-3329-100"
Im not familiar with the split method, if anyone can enlight me about this ^^
You can use substring method to get rid of the leading zeros...
String myString = "2020-LI50532-3329-00100";
String[] data = myString.split("-");
data[3] = data[3].substring(2);
StringBuilder sb = new StringBuilder();
sb.append(data[0] + "-" + data[1] + "-" + data[2] + "-" + data[3]);
String result = sb.toString();
System.out.println(result);
Assuming that we want to remove the leading zeroes of ONLY the last block, maybe we can:
Extract the last block
Convert it to Integer and back to String to remove leading zeroes
Replace the last block with the String obtained in above step
Something like this:
public String removeLeadingZeroesFromLastBlock(String text) {
int indexOfLastDelimiter = text.lastIndexOf('-');
if (indexOfLastDelimiter >= 0) {
String lastBlock = text.substring(indexOfLastDelimiter + 1);
String lastBlockWithoutLeadingZeroes = String.valueOf(Integer.valueOf(lastBlock)); // will throw exception if last block is not an int
return text.substring(0, indexOfLastDelimiter + 1).concat(lastBlockWithoutLeadingZeroes);
}
return text;
}
Solution using regex:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(parse("2020-LI50532-3329-00100"));
System.out.println(parse("2020-LI50532-3329-00001"));
System.out.println(parse("2020-LI50532-03329-00100"));
System.out.println(parse("2020-LI50532-03329-00001"));
}
static String parse(String str) {
return str.replaceAll("0+(?=[1-9]\\d*$)", "");
}
}
Output:
2020-LI50532-3329-100
2020-LI50532-3329-1
2020-LI50532-03329-100
2020-LI50532-03329-1
Explanation of the regex:
One or more zeros followed by a non-zero digit which can be optionally followed by any digit(s) until the end of the string (specified by $).
Solution without using regex:
You can do it also by using Integer.parseInt which can parse a string like 00100 into 100.
public class Main {
public static void main(String[] args) {
// Test
System.out.println(parse("2020-LI50532-3329-00100"));
System.out.println(parse("2020-LI50532-3329-00001"));
System.out.println(parse("2020-LI50532-03329-00100"));
System.out.println(parse("2020-LI50532-03329-00001"));
}
static String parse(String str) {
String[] parts = str.split("-");
try {
parts[parts.length - 1] = String.valueOf(Integer.parseInt(parts[parts.length - 1]));
} catch (NumberFormatException e) {
// Do nothing
}
return String.join("-", parts);
}
}
Output:
2020-LI50532-3329-100
2020-LI50532-3329-1
2020-LI50532-03329-100
2020-LI50532-03329-1
you can convert the last string portion to integer type like below for removing unused zeros:
String myString = "2020-LI50532-3329-00100";
String[] data = myString.split("-");
data[3] = data[3].substring(2);
StringBuilder sb = new StringBuilder();
sb.append(data[0] + "-" + data[1] + "-" + data[2] + "-" + Integer.parseInt(data[3]));
String result = sb.toString();
System.out.println(result);
You should avoid String manipulation where possible and rely on existing types in the Java language. One such type is the Integer. It looks like your code consists of 4 parts - Year (Integer) - String - Integer - Integer.
So to properly validate it I would use the following code:
Scanner scan = new Scanner("2020-LI50532-3329-00100");
scan.useDelimiter("-");
Integer firstPart = scan.nextInt();
String secondPart = scan.next();
Integer thirdPart = scan.nextInt();
Integer fourthPart = scan.nextInt();
Or alternatively something like:
String str = "00100";
int num = Integer.parseInt(str);
System.out.println(num);
If you want to reconstruct your original value, you should probably use a NumberFormat to add the missing 0s.
The main points are:
Always try to reuse existing code and tools available in your language
Always try to use available types (LocalDate, Integer, Long)
Create your own types (classes) and use the expressiveness of the Object Oriented language
public class Test {
public static void main(String[] args) {
System.out.println(trimLeadingZeroesFromLastPart("2020-LI50532-03329-00100"));
}
private static String trimLeadingZeroesFromLastPart(String input) {
String delem = "-";
String result = "";
if (input != null && !input.isEmpty()) {
String[] data = input.split(delem);
StringBuilder tempStrBldr = new StringBuilder();
for (int idx = 0; idx < data.length; idx++) {
if (idx == data.length - 1) {
tempStrBldr.append(trimLeadingZeroes(data[idx]));
} else {
tempStrBldr.append(data[idx]);
}
tempStrBldr.append(delem);
}
result = tempStrBldr.substring(0, tempStrBldr.length() - 1);
}
return result;
}
private static String trimLeadingZeroes(String input) {
int idx;
for (idx = 0; idx < input.length() - 1; idx++) {
if (input.charAt(idx) != '0') {
break;
}
}
return input.substring(idx);
}
}
Output:
2020-LI50532-3329-100

Finding Pattern from one string to apply to another string - Java

So I have a string like this: <em>1234</em>56.70
it's basically a number where the em tags help identify what to highlight in the string
I need to first convert the string to an actual number with the current locale format. So I remove the em tags (replaceAll by emptyString) and then use the numberFormat java API to get a string like: $123,456.70
The problem with this is, I lost the highlight (em) tags. So I need to put it back in the string that is formatted, something like this: <em>$123,4</em>56.70
highlightValue = "<em>1234</em>56.70";
highlightValue = highlightValue.replaceAll("<em>", "").replaceAll("</em>", ""); // highlightValue is now 123456.70
highlightValue = numberFormat.convertToFormat(highlightValue, currencyCode); // highlightValue is now $123,456.70
highlightValue = someFunction(highlightValue); // this function needs to return <em>$123,4</em>56.70
I am not sure what approach to use. I was trying pattern matching but didn't know how to achieve it.
All help appreciated !
I am assuming that you want to highlight the number from starting up to some number of digits.This can be done.
In the initial string count the number of digits after which the tag is present. The starting tag will always be placed at the beginning. It is the ending tag you have to worry about. Now count the number of digits, excluding any other symbols.When the required number of digits have been passed, again place the tag. Either you can create a StringBuilder from the String highlighted and insert the tag string directly, or divide the string into two substrings and then join them together with the tag string in the middle.
Hope this helped.
I took an approach, where I count the numbers in front of the tag, in the middle of the tag - as I think no formatting will actually change the numbers(assuming you don't add leading zeroes) and after that I insert back the tag based on the numbers which were in front of the tag or for the closing tag in front and inside
so this is the code:
public static void main(String[] args) {
String input1 = "<em>1234</em>56.70";
String result1 = formatString(input1, "em");
System.out.printf("input1 = %s%n", input1);
System.out.printf("result1 = %s%n", result1);
String input2 = "<em>8127</em>29.12";
String result2 = formatString(input2, "em");
System.out.printf("input2 = %s%n", input2);
System.out.printf("result2 = %s%n", result2);
}
private static String formatString(String input, String tagName) {
String tagOpening = String.format("<%s>", tagName);
int tagOpeningLength = tagOpening.length();
String tagClosing = String.format("</%s>", tagName);
int tagClosingLength = tagClosing.length();
int inputLength = input.length();
int tagOpeningPos = input.indexOf(tagOpening);
int tagClosingPos = input.indexOf(tagClosing, tagOpeningPos);
String beforeTag;
if(tagOpeningPos > 0)
beforeTag = input.substring(0, tagOpeningPos);
else
beforeTag = "";
int digitsInBeforeTag = countNumbers(beforeTag);
String tagValue;
if(tagOpeningPos + tagOpeningLength < tagClosingPos)
tagValue = input.substring(tagOpeningPos + tagOpeningLength, tagClosingPos);
else
tagValue = "";
int digitsInTagValue = countNumbers(tagValue);
String afterTag;
if((tagClosingPos + tagClosingLength) < inputLength)
afterTag = input.substring(tagClosingPos + tagClosingLength);
else
afterTag = "";
String valueToBeFormatted = beforeTag + tagValue + afterTag;
double value = Double.parseDouble(valueToBeFormatted);
NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
String formattedValue = nf.format(value);
int newEmOpeningPos = findSubstringWithThisManyNumbers(formattedValue, digitsInBeforeTag);
int newEmClosingPos = findSubstringWithThisManyNumbers(formattedValue, digitsInBeforeTag+digitsInTagValue);
StringBuilder result = new StringBuilder();
result.append(formattedValue.substring(0, newEmOpeningPos));
result.append(tagOpening);
result.append(formattedValue.substring(newEmOpeningPos, newEmClosingPos));
result.append(tagClosing);
result.append(formattedValue.substring(newEmClosingPos));
return result.toString();
}
private static int findSubstringWithThisManyNumbers(String input, int digitCount) {
int pos = 0;
int counter = 0;
for(char c : input.toCharArray()) {
if(counter >= digitCount)
break;
if(Character.isDigit(c))
counter++;
pos++;
}
return pos;
}
private static int countNumbers(String str) {
int result = 0;
for(char c : str.toCharArray())
if(Character.isDigit(c))
result++;
return result;
}
the output was
input1 = <em>1234</em>56.70
result1 = <em>123,4</em>56.7
input2 = <em>8127</em>29.12
result2 = <em>812,7</em>29.12
I don't know how can this be practical. But anyway.
String highlightValue = "0<em>1234</em>56.70";
int startIndex = highlightValue.indexOf("<em>");
String startString = highlightValue.substring(0, startIndex);
String endString = highlightValue.substring(highlightValue.indexOf("</em>") + "</em>".length());
highlightValue = highlightValue.replaceAll("<em>", "").replaceAll("</em>", "");
highlightValue = numberFormat.convertToFormat(highlightValue, currencyCode);
// highlightValue is now $123,456.70
int endIndex = highlightValue.indexOf(endString);
highlightValue = startString + "<em>" + highlightValue.substring(0, endIndex) + "</em>" + endString;
System.out.println(highlightValue);
// 0<em>$123,4</em>56.70

Java - Spintax , what should i do?

I just wrote my program in C# but I want rewrite it in Java. I want create spintax text.
My C# code:
static string spintax(Random rnd, string str)
{
// Loop over string until all patterns exhausted.
string pattern = "{[^{}]*}";
Match m = Regex.Match(str, pattern);
while (m.Success)
{
// Get random choice and replace pattern match.
string seg = str.Substring(m.Index + 1, m.Length - 2);
string[] choices = seg.Split('|');
str = str.Substring(0, m.Index) + choices[rnd.Next(choices.Length)] + str.Substring(m.Index + m.Length);
m = Regex.Match(str, pattern);
}
// Return the modified string.
return str;
}
I've Updated My Code to
static String Spintax(Random rnd,String str)
{
String pat = "\\{[^{}]*\\}";
Pattern ma;
ma = Pattern.compile(pat);
Matcher mat = ma.matcher(str);
while(mat.find())
{
String segono = str.substring(mat.start() + 1,mat.end() - 1);
String[] choies = segono.split("\\|",-1);
str = str.substring(0, mat.start()) + choies[rnd.nextInt(choies.length)].toString() + str.substring(mat.start()+mat.group().length());
mat = ma.matcher(str);
}
return str;
}
works like a charm :D thanks all for your support..
You need to escape the brackets
String pat = "\\{[^{}]*\\}";

Replace all occurences of certain char and get all variations

I have a word on which I need to replace a certain character with an asterisk, but I need to get all the replaced variations from this word. For eg. I want to replace character 'e' with an asterisk in:
String word = telephone;
but to get this list as a result:
List of words = [t*lephone, tel*phone, telephon*, t*l*phone, t*lephon*, tel*phon*, t*l*phon*];
Is there a quick way to do this in Java?
The following code will do that in a recursive way:
public static Set<String> getPermutations(final String string, final char c) {
final Set<String> permutations = new HashSet<>();
final int indexofChar = string.indexOf(c);
if (indexofChar <= 0) {
permutations.add(string);
} else {
final String firstPart = string.substring(0, indexofChar + 1);
final String firstPartReplaced = firstPart.replace(c, '*');
final String lastPart = string.substring(indexofChar + 1, string.length());
for (final String lastPartPerm : getPermutations(lastPart, c)) {
permutations.add(firstPart + lastPartPerm);
permutations.add(firstPartReplaced + lastPartPerm);
}
}
return permutations;
}
It adds the original String to the output, so:
public static void main(String[] args) {
String word = "telephone";
System.out.println(getPermutations(word, 'e'));
}
Outputs:
[telephone, t*lephone, tel*phone, t*l*phone, telephon*, t*lephon*, tel*phon*, t*l*phon*]
But you can always call remove on the returned Set with the original word.

Categories

Resources