ben
ben

Reputation: 97

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);
}

}

Upvotes: 2

Views: 1722

Answers (3)

nem035
nem035

Reputation: 35481

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);

Upvotes: 0

Stephen C
Stephen C

Reputation: 718678

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.

Upvotes: 4

Secondo
Secondo

Reputation: 451

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

Upvotes: 0

Related Questions