How to replace a single char at an index by a string? - java

I have a String "speed,7,red,fast". I want to replace the 7 by a String "Seven". How do I do that ?
More details -
7 can be replaced by ANY string and not just "Seven". It could also be "SevenIsHeaven".
I don't want to replace all occurrences of 7. Only 7 at the specified index, ie use the index of 7 to replace 7 by some string.

replaceAll("7", "Seven") //simple as that
EDIT
Then you should look for the specified index.
String input = "test 7 speed,7,red,fast yup 7 tr";
int indexInteresdIn = 13;
if(input.charAt(indexInteresdIn) == '7'){
StringBuilder builder = new StringBuilder(input);
builder.replace(indexInteresdIn, indexInteresdIn+1, "Seven");
System.out.println(builder.toString());
}

Because String is immutable you should use StringBuilder for better performance.
http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html
yourStringBuiler.replace(
yourStringBuiler.indexOf(oldString),
yourStringBuiler.indexOf(oldString) + oldString.length(),
newString);`
If you want to replace a whole String like the String.replaceAll() does you could create an own function like this:
public static void replaceAll(StringBuilder builder, String from, String to)
{
int index = builder.indexOf(from);
while (index != -1)
{
builder.replace(index, index + from.length(), to);
index += to.length(); // Move to the end of the replacement
index = builder.indexOf(from, index);
}
}
Source:
Replace all occurrences of a String using StringBuilder?
However if you doesn't need it frequently and performance is not that important a simple String.replaceAll() will do the trick, too.

How about simply like below ?
String str = "speed,7,red,fast";
str = str.replace("7", "Seven");
7 can be replaced by ANY string and not just "Seven". It could also be
"SevenIsHeaven". I don't want to replace all occurrences of 7. Only 7
at the specified index.
Or if you wanna use regex to replace the first numeric to a meaningful String.
String str = "speed,7,red,fast";
str = str.replaceFirst("\\d", "Seven");

better way is to store the string itself in an array, spiting it at a space.
String s[];
static int index;
s = in.readLine().spilt(" ");
Now scan the array for the specified word, at the specified index and replace that with the String you desire.
for(int i =0;i<s.length; i++)
{
if((s[i] == "7")&&(i==index))
{
s[i]= "Seven";
}
}

Related

Mask part of the String data which is of different lengths using Java

I am in need to mask PII data for my application. The PII data will be of String format and of variable lengths, as it may include name, address, mail id's etc.
So i need to mask these data before logging them, it should not be a full mask instead, if the length of string is less than or equal to 8 characters then mask the first half with "XXX etc.."
If the length is more than 8 then mask the first and last portion of the string such that only the mid 5 characters are visible.
I know we can do this using java sub-stringa nd iterating over the string, but want to know if there is any other simple solution to address this.
Thanks in advance
If you are using Apache Commons, you can do like
String maskChar = "*";
//number of characters to be masked
String maskString = StringUtils.repeat( maskChar, 4);
//string to be masked
String str = "FirstName";
//this will mask first 4 characters of the string
System.out.println( StringUtils.overlay(str, maskString, 0, 4) );
You can check the string length before generating maskString using if else statement.
You can use this function; change the logic of half's as per your needs:
public static String maskedVariableString(String original)
{
String maskedString = null;
if(original.length()<9)
{
int half = original.length()/2;
StringBuilder sb =new StringBuilder("");
for(int i=0;i<(original.length()-half);i++)
{
sb.append("X");
}
maskedString = original.replaceAll("\\b.*(\\d{"+half+"})", sb.toString()+"$1");
}
else
{
int maskLength = original.length()-5;
int firstMaskLength = maskLength/2;
int secondMaskLength = maskLength-firstMaskLength;
StringBuilder sb =new StringBuilder("");
for(int i=0;i<firstMaskLength;i++)
{
sb.append("X");
}
String firstMask = sb.toString();
StringBuilder sb1 =new StringBuilder("");
for(int i=0;i<secondMaskLength;i++)
{
sb1.append("X");
}
String secondMask = sb1.toString();
maskedString = original.replaceAll("\\b(\\d{"+firstMaskLength+"})(\\d{5})(\\d{"+secondMaskLength+"})", firstMask+"$2"+secondMask);
}
return maskedString;
}
Explanation:
() groups the regular expression and we can use $ to access this group($1, $2,$3).
The \b boundary helps check that we are the start of the digits (there are other ways to do this, but here this will do).
(\d{+half+}) captures (half) no of digits to Group 1. The same happens in the else part also.

Ignoring upper/lowercase strings

My goal is to change any form of the word "java" in a sentence to "JAVA".I've got everything done but my code won't read in mixed cases for example:JaVa, JAva,etc. I know I am suppose to use toUpperCase and toLowerCase or equalsIgnoreCase but I am not sure how to use it properly. I am not allowed to use replace or replace all, teacher wants substring method.
Scanner input=new Scanner(System.in);
System.out.println("Enter a sentence with words including java");
String sentence=input.nextLine();
String find="java";
String replace="JAVA";
String result="";
int n;
do{
n=sentence.indexOf(find);
if(n!=-1){
result =sentence.substring(0,n);
result=result +replace;
result = result + sentence.substring(n+find.length());
sentence=result;
}
}while(n!=-1);
System.out.println(sentence);
}
}
You can't do that using String.indexOf because it is case sensitive.
The simple solution is to use a regex with a case insensitive pattern; e.g.
Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(str).replaceAll(repl);
That also has the benefit of avoiding the messy string-bashing you are currently using to do the replacement.
In your example, your input string is also valid as a regex ... because it doesn't include any regex meta-characters. If it did, then the simple workaround is to use Pattern.quote(str) which will treat the meta-characters as literal matches.
It is also worth nothing that String.replaceAll(...) is a "convenience method" for doing a regex replace on a string, though you can't use it for your example because it does case sensitive matching.
For the record, here is a partial solution that does the job by string-bashing. #ben - this is presented for you to read and understand ... not to copy. It is deliberately uncommented to encourage you to read it carefully.
// WARNING ... UNTESTED CODE
String input = ...
String target = ...
String replacement = ...
String inputLc = input.lowerCase();
String targetLc = target.lowerCase();
int pos = 0;
int pos2;
while ((pos2 = inputLc.indexOf(targetLc, pos)) != -1) {
if (pos2 - pos > 0) {
result += input.substring(pos, pos2);
}
result += replacement;
pos = pos2 + target.length();
}
if (pos < input.length()) {
result += input.substring(pos);
}
It probably be more efficient to use a StringBuilder instead of a String for result.
you are allowed to use toUpperCase() ? try this one
Scanner input=new Scanner(System.in);
System.out.println("Enter a sentence with words including java");
String sentence=input.nextLine();
String find="java";
String replace="JAVA";
String result="";
result = sentence.toLowerCase();
result = result.replace(find,replace);
System.out.println(result);
}
reply with the result :))
Update : Based on
I've got everything done but my code won't read in mixed cases for
example:JaVa, JAva,etc.
you can use your code
Scanner input=new Scanner(System.in);
System.out.println("Enter a sentence with words including java");
String sentence=input.nextLine();
String find="java";
String replace="JAVA";
String result="";
int n;
do{
//for you to ignore(converts the sentence to lowercase) either lower or upper case in your sentence then do the nxt process
sentence = sentence.toLowerCase();
n=sentence.indexOf(find);
if(n!=-1){
result =sentence.substring(0,n);
result=result +replace;
result = result + sentence.substring(n+find.length());
sentence=result;
}
}while(n!=-1);
System.out.println(sentence);
}
Update 2 : I put toLowerCase Convertion outside the loop.
public static void main(String[] args){
String sentence = "Hello my name is JAva im a jaVa Man with a jAvA java Ice cream";
String find="java";
String replace="JAVA";
String result="";
int n;
//for you to ignore(converts the sentence to lowercase) either lower or upper case in your sentence then do the nxt process
sentence = sentence.toLowerCase();
System.out.println(sentence);
do{
n=sentence.indexOf(find);
if(n!=-1){
result =sentence.substring(0,n);
result=result +replace;
result = result + sentence.substring(n+find.length());
sentence=result;
}
}while(n!=-1);
System.out.println(sentence);
}
RESULT
hello my name is java im a java man with a java java ice cream
hello my name is JAVA im a JAVA man with a JAVA JAVA ice cream
A quick solution would be to remove your do/while loop entirely and just use a case-insensitive regex with String.replaceAll(), like:
sentence = sentence.replaceAll("(?i)java", "JAVA");
System.out.println(sentence);
Or, more general and according to your variable namings:
sentence = sentence.replaceAll("(?i)" + find, replace);
System.out.println(sentence);
Sample Program
EDIT:
Based on your comments, if you need to use the substring method, here is one way.
First, since String.indexOf does case-sensitive comparisons, you can write your own case-insensitive method, let's call it indexOfIgnoreCase(). This method would look something like:
// Find the index of the first occurrence of the String find within the String str, starting from start index
// Return -1 if no match is found
int indexOfIgnoreCase(String str, String find, int start) {
for(int i = start; i < str.length(); i++) {
if(str.substring(i, i + find.length()).equalsIgnoreCase(find)) {
return i;
}
}
return -1;
}
Then, you can use this method in the following manner.
You find the index of the word you need, then you add the portion of the String before this word (up to the found index) to the result, then you add the replaced version of the word you found, then you add the rest of the String after the found word.
Finally, you update the starting search index by the length of the found word.
String find = "java";
String replace = "JAVA";
int index = 0;
while(index + find.length() <= sentence.length()) {
index = indexOfIgnoreCase(sentence, find, index); // use the custom indexOf method here
if(index == -1) {
break;
}
sentence = sentence.substring(0, index) + // copy the string up to the found word
replace + // replace the found word
sentence.substring(index + find.length()); // copy the remaining part of the string
index += find.length();
}
System.out.println(sentence);
Sample Program
You could use a StringBuilder to make this more efficient since the + operator creates a new String on each concatenation. Read more here
Furthermore, you could combine the logic in the indexOfIgnoreCase and the rest of the code in a single method like:
String find = "java";
String replace = "JAVA";
StringBuilder sb = new StringBuilder();
int i = 0;
while(i + find.length() <= sentence.length()) {
// if found a match, add the replacement and update the index accordingly
if(sentence.substring(i, i + find.length()).equalsIgnoreCase(find)) {
sb.append(replace);
i += find.length();
}
// otherwise add the current character and update the index accordingly
else {
sb.append(sentence.charAt(i));
i++;
}
}
sb.append(sentence.substring(i)); // append the rest of the string
sentence = sb.toString();
System.out.println(sentence);

First char to upper case [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to upper case every first letter of word in a string?
Most efficient way to make the first character of a String lower case?
I want to convert the first letter of a string to upper case. I am attempting to use replaceFirst() as described in JavaDocs, but I have no idea what is meant by regular expression.
Here is the code I have tried so far:
public static String cap1stChar(String userIdea)
{
String betterIdea, userIdeaUC;
char char1;
userIdeaUC = userIdea.toUpperCase();
char1 = userIdeaUC.charAt(0);
betterIdea = userIdea.replaceFirst(char1);
return betterIdea;
}//end cap1stChar
The compiler error is that the argument lists differ in lengths. I presume that is because the regex is missing, however I don't know what that is exactly.
Regular Expressions (abbreviated "regex" or "reg-ex") is a string that defines a search pattern.
What replaceFirst() does is it uses the regular expression provided in the parameters and replaces the first result from the search with whatever you pass in as the other parameter.
What you want to do is convert the string to an array using the String class' charAt() method, and then use Character.toUpperCase() to change the character to upper case (obviously). Your code would look like this:
char first = Character.toUpperCase(userIdea.charAt(0));
betterIdea = first + userIdea.substring(1);
Or, if you feel comfortable with more complex, one-lined java code:
betterIdea = Character.toUpperCase(userIdea.charAt(0)) + userIdea.substring(1);
Both of these do the same thing, which is converting the first character of userIdea to an upper case character.
Or you can do
s = Character.toUpperCase(s.charAt(0)) + s.substring(1);
public static String cap1stChar(String userIdea)
{
char[] stringArray = userIdea.toCharArray();
stringArray[0] = Character.toUpperCase(stringArray[0]);
return userIdea = new String(stringArray);
}
Comilation error is due arguments are not properly provided, replaceFirst accepts regx as initial arg. [a-z]{1} will match string of simple alpha characters of length 1.
Try this.
betterIdea = userIdea.replaceFirst("[a-z]{1}", userIdea.substring(0,1).toUpperCase())
String toCamelCase(String string) {
StringBuffer sb = new StringBuffer(string);
sb.replace(0, 1, string.substring(0, 1).toUpperCase());
return sb.toString();
}
userIdeaUC = userIdea.substring(0, 1).toUpperCase() + userIdea.length() > 1 ? userIdea.substring(1) : "";
or
userIdeaUC = userIdea.substring(0, 1).toUpperCase();
if(userIdea.length() > 1)
userIdeaUC += userIdea.substring(1);
For completeness, if you wanted to use replaceFirst, try this:
public static String cap1stChar(String userIdea)
{
String betterIdea = userIdea;
if (userIdea.length() > 0)
{
String first = userIdea.substring(0,1);
betterIdea = userIdea.replaceFirst(first, first.toUpperCase());
}
return betterIdea;
}//end cap1stChar

Short string format

I've an array with hundreds of string values, Is it possible to use specific formats to make them shorter?
e.g
Normal -> "Hello John, What's up?!"
With short format -> "Hello John..."
After using substring, I got errors.
private String[] finalString;
for (int i = 0; i < arrays.PodcastTitle.length; i++) {
finalString[i] = arrays.PodcastTitle[i].substring(0, 5);
}
Since you haven't given any details, this is the shortest approach :
String little = normalString.substring(0, 10); // use anything 5 or 10 or 15, depending on how short you want to make your String
From your edit:
Please change:
private String[] finalString;
to:
private String[] finalString = new String[whateverSizeYouWant];
String toLitteString(String str, int length) {
if (str.length() > length) return str.substring(0, length) + "...";
return str;
}
Function that will truncate longer strings to length (and add a "...") or return the short string. If you want the length to include the "..." then just change length to length - 3.
Why won't you consider implementing a method that takes a String argument, explodes it by space character and returns the String with required number of words in it?

Remove last set of value from a comma separated string in java

I wan to remove the last set of data from string using java.
For example I have a string like A,B,C, and I want to remove ,C, and want to get the out put value like A,B . How is it possible in java? Please help.
String start = "A,B,C,";
String result = start.subString(0, start.lastIndexOf(',', start.lastIndexOf(',') - 1));
Here is a fairly "robust" reg-exp solution:
Pattern p = Pattern.compile("((\\w,?)+),\\w+,?");
for (String test : new String[] {"A,B,C", "A,B", "A,B,C,",
"ABC,DEF,GHI,JKL"}) {
Matcher m = p.matcher(test);
if (m.matches())
System.out.println(m.group(1));
}
Output:
A,B
A
A,B
ABC,DEF,GHI
Since there may be a trailing comma, something like this (using org.apache.commons.lang.StringUtils):
ArrayList<String> list = new ArrayList(Arrays.asList(myString.split()));
list.remove(list.length-1);
myString = StringUtils.join(list, ",");
You can use String#lastIndexOf to find the index of the second-to-last comma, and then String#substring to extract just the part before it. Since your sample data ends with a ",", you'll need to use the version of String#lastIndexOf that accepts a starting point and have it skip the last character (e.g., feed in the string's length minus 1).
I wasn't going to post actual code on the theory better to teach a man to fish, but as everyone else is:
String data = "A,B,C,";
String shortened = data.substring(0, data.lastIndexOf(',', data.length() - 2));
You can use regex to do this
String start = "A,B,C,";
String result = start.replaceAll(",[^,]*,$", "");
System.out.println(result);
prints
A,B
This simply erases the the 'second last comma followed by data followed by last comma'
If full String.split() is not possible, the how about just scanning the string for comma and stop after reaching 2nd, without including it in final answer?
String start = "A,B";
StringBuilder result = new StringBuilder();
int count = 0;
for(char ch:start.toCharArray()) {
if(ch == ',') {
count++;
if(count==2) {
break;
}
}
result.append(ch);
}
System.out.println("Result = "+result.toString());
Simple trick, but should be efficient.
In case you want last set of data removed, irrespective of how much you want to read, then
start.substring(0, start.lastIndexOf(',', start.lastIndexOf(',')-1))
Another way to do this is using a StringTokenizer:
String input = "A,B,C,";
StringTokenizer tokenizer = new StringTokenizer(input, ",");
String output = new String();
int tokenCount = tokenizer.countTokens();
for (int i = 0; i < tokenCount - 1; i++) {
output += tokenizer.nextToken();
if (i < tokenCount - 1) {
output += ",";
}
}
public string RemoveLastSepratorFromString(string input)
{
string result = input;
if (result.Length > 1)
{
result = input.Remove(input.Length - 1, 1);
}
return result;
}
// use from above method
string test = "1,2,3,"
string strResult = RemoveLastSepratorFromString(test);
//output --> 1,2,3

Categories