Use Scanner class to replace all occurrence of string with another - java

i want to scan a string with a Scanner class and i want to replace each "is" word by "is not" expect embedded "is " like "this" for example
good morning this is my name became good morning this is not my name
i write the snippet of code
public static void main(String[] args) {
String chaine="good morning this is my name";
Scanner sc=new Scanner(chaine);
while(sc.hasNext()) {
String word=sc.next();
if(word.equals("is"))
chaine=chaine.replace(word, "is not");
}
System.out.println(chaine);
}
when i execute this program it print:
good morning this not is not my name but i want to print good morning this is not my name

Sorry for before I did not see what you exactly want. I modify a little your code. I use StringBuilder to store the parts of the words and I close the Scanner.
public static void main(String[] args) {
String chaine="good morning this is my name";
Scanner sc=new Scanner(chaine);
StringBuilder sb = new StringBuilder();
while(sc.hasNext()) {
String word=sc.next();
if(word.equals("is"))
{
sb.append("is not");
}
else
{
sb.append(word);
}
//Add space after every added word.
sb.append(" ");
}
sc.close();
String result = sb.toString();
//Call trim to remove the space after the last word
System.out.println(result.trim());
}
Good Luck to all!

I have attached a solution to your problem. It's a similar approach with the correction from the solution already been submitted. Consider the use case where the user will type "Good morning this is not my name". In this situation also the code will replace "is" with "is not". And the output will be "Good morning this is not not my name". You can consider this solution where we can check whether it's already "is not" or not.
(I am assuming here that you just want to correct "is" to "is not" and if you user types "is not" then you will not change anything. If this what you want then here is the correct code.)
StringBuilder sb=new StringBuilder();
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
String word=sc.nextLine();
if(!word.contains("is not"))
sb.append(word.replace("is","is not"));
else sb.append(word);
sb.append("\n"); //new line to get same string as
// user's input
}
sc.close();
System.out.println(sb.toString());
If you want to use the earlier solution then you have to put a condition to check whether the user has already given a correct input or not.

You can use replace method for replace substrings.
But anyway if you don't need to replace parts of other words, you just should write " is " in brackets with spaces.

this worked
if(word.equals("is")) {
chaine=chaine.replaceFirst(" "+word+" ", " is not ");
}
replace function replaces all the occurences of the word you give, and you are giving it "is" which is included in "this", just put some spaces to prevent this. Using replace first will replace the first occurence, instead of replace which replaces everything.
even if using Scanner it self seems not to be a right practice

Since you are using Java's Scanner class and utilizing the Scanner#next() method in conjunction with the Scanner#hasNext() method you can expect to retrieve each word within the string as a token for each iteration of your while loop.
This is a better mechanism for what you are trying to do (with Scanner) when specifically utilizing the String#replace() method because the Scanner#next() method retrieves each word on its own based on the default White-Space delimiter (since you have not specified a delimiter using the Scanner#useDelimiter() method - Note this: more later).
As you may already know the String#replace() method will replace all occurrences of a substring within a string whether it's inside a word or the word itself so you don't want to play that card in this particular case.
Your problem is that you are using the String#replace() method against the entire string rather than just the found word itself:
if(word.equals("is")) {
chaine = chaine.replace(word, "is not");
}
This will of course replace all occurrences of the substring is throughout the entire String (including in the word "this" which is obviously not desired. It should be:
if(word.equals("is")) {
word = word.replace(word, "is not");
}
and then append the contents of the word variable to a particular string build. You will need to rebuild the string as you are finished processing each word retrieved by the Scanner#next() method upon each iteration of the while loop.
For this small use case, to rebuild the string you can use the String Concatenation Operator (+):
String finalString = ""; // Will hold the string build
while (sc.hasNext()) {
String word = sc.next();
if (word.equals("is")) {
word = word.replace(word, "is not");
}
// Rebuild the string upon each iteration
finalString+= (!finalString.equals("") ? " " + word : word);
}
In the code line above: finalString+= (finalString.equals("") ? word : " " + word); you can see the use of the String Concatenation Operator (+): finalString+= but there is also an equals character after it. This is basically telling the compiler that finalyString is to hold and maintain the string data that is already contained within it, in other words: finalyString = finallyString +.
In the above code line you can also see the use of a Ternary Operator so as to apply white-spaces where needed:
(finalString+= (!finalString.equals("") ? " " + word : word);
A ternary operator works in the very same fashion as an if/else scenario. Using if/else it would look like:
// If finalString is NOT empty
if (!finalString.equals("") {
// Append a white-space and then the word
finalString+= " " + word;
}
// otherwise if finalString is empty
else {
// Just append the word
finalString+= word;
}
You can quickly see why using a Ternary Operator is a good way to go.
Another way you can rebuild the string is by utilizing the StringBuilder class. It is good to use this class for building lots of strings through lots of iterations. It's good to get into the habit of using this class even for small situations like this:
String chaine = "good morning this is my name";
Scanner sc = new Scanner(chaine);
StringBuilder sb = new StringBuilder();
while (sc.hasNext()) {
String word = sc.next();
if (word.equals("is")) {
word = word.replace(word, "is not");
}
/* If the 'string build' is not empty then add
a white-space in preperation for next word. */
if (!sb.toString().equals("")) {
sb.append(" ");
}
// Append next word (modified or not)
sb.append(word);
}
chaine = sb.toString();
This is all fine and good but there is one little problem with all of this. What if the main string supplied has padded or additional white-spaces in specific locations along that String we want to remain? The above build examples remove them.
The Scanner#hasNext() with the Scanner#next() ignores all white-spaces when each token (word) is retrieved. This can actually be a major problem in a lot of situations but not all is lost since there is a simple fix.
Remember that Scanner#useDelimiter() method we touched on earlier? Well, use it:
Scanner sc = new Scanner(chaine).useDelimiter(" ");
Now white-spaces will not be ignored and are retrieved as Null Strings ("") and processed within our code with:
// In the String Concatenation Operator code
finalString+= (!finalString.equals("") ? " " + word : word);
O R
// In the StringBuilder code
if (!sb.toString().equals("")) {
sb.append(" ");
}
But this does not take care of Leading white-spaces in the main string. To take care of Leading white-spaces we need to add a wee bit more code:
// In the String Concatenation Operator code
finalString+= (!finalString.equals("") || word.equals("") ? " " + word : word);
O R
// In the StringBuilder code
if (!sb.toString().equals("") || word.equals("")) {
sb.append(" ");
}
There, done....but you know, you can accomplish the same thing with a single line of code using the String#replaceAll() method:
String chaine = "good morning this is my name";
// A Single line of code (all whitespaces remain intact).
chaine = chaine.replaceAll("\\bis\\b", "is not");
The String#replaceAll() method allows for Regular Expressions (RegEx) to be utilized arguably making life soooo much easier in a lot of cases.
The regular expression ("\\bis\\b") passed to the replaceAll() method above contains the Word Boundary meta character \b which checks if a string or substring pattern begins and ends on a word boundary and the word within the expression is of course "is". You can read about Boundary Matchers here. If you want to play around with Regular Expressions and test them then you can do it at RegEx101.com.

Related

Stack Class seperating elements

Hello everyone im trying to make a code to remove
vowels and consonants when a user types a string
but i seem to fail at the code and i need to use a stack class to do it
Sample Output should be like this and will ignore non alphabet characters
Enter a String : hello1234!##$
Vowels : eo
Consonant : hll
Final contents : 1234!##$
can someone fix my code
this is the error I get
enter image description here
import java.util.Scanner;
import java.util.Stack;
public class PushPop
{
//I used the push and pop methods
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.print("Enter a String: ");
String str = sc.nextLine();
Stack<String> String = new Stack();
String.push(str);
String vowels = String.pop();
vowels = vowels.replace("[aeiou]", "");
String consonants = String.pop();
consonants = consonants.replace("[qbcdfghjklmnpqrstvwxyz]", "");
System.out.println("Vowels: "+ vowels);
System.out.print("Consonant: "+ consonants);
//this will print what is left after popping the elements
System.out.print("Final contents: "+ str);
}
}
If you just want to remove all vowels and consonants form the user's input, a Stack is not needed (at least if you use the ready made Java's Pattern in some way). In fact, you get the Exception because you try to pop from the Stack twice, while having only pushed once. In particular you first push the user's input str, then pop it to the variable vowels (so the Stack is now empty) and then you pop from it again, this time into the variable consonants.
vowels = vowels.replace("[aeiou]", "");
According to documentation of replace it will replace all literals with the second argument. This means that it will replace all Strings matching the literal "[aeiou]" (if it exists as is in the user's input) with the empty String. Instead you should use replaceAll method which takes a regex (ie Regular Expression) as the first argument:
str = str.replaceAll("[aeiou]", "");
The regular expressions you are using seem correct for your problem, although you want to first remove the vowels from the user's input and then from that String (which is the result of the user's input by removing all vowels) remove also the consonants. So the logic should instead be:
String str = sc.nextLine(); //Get user input.
str = str.replaceAll("[aeiou]", ""); //Remove vowels.
str = str.replaceAll("[qbcdfghjklmnpqrstvwxyz]", ""); //Remove consonants.
System.out.println(str); //Print result.
which, if you combine the two regexes toghether in a single operation, can be shortened to:
String str = sc.nextLine();
str = str.replaceAll("[aeiouqbcdfghjklmnpqrstvwxyz]", "");
System.out.println(str);
which, if you realize that these are all alphabet letters, can be shortened even further with:
str = str.replaceAll("[a-z]", "");
and if you also want both upper and lower case letters, then you can do:
str = str.replaceAll("[a-zA-Z]", "");
which is equivalent to:
str = str.replaceAll("\\p{Alpha}", "");
All those examples can be made clear for someone if they read the documentation on how a Java Pattern is constructed, so it may help to take a look there, if you didn't already know it.
i need to use a stack class to do it
Can you please explain what is the desired behaviour, and how a Stack needs to be used? Because it seems like you just want to remove all alphabet letters. Are you required to not use regexes for this?

Storing words from a .txt file into a String array

I was going through the answers of this question asked by someone previously and I found them to be very helpful. However, I have a question about the highlighted answer but I wasn't sure if I should ask there since it's a 6 year old thread.
My question is about this snippet of code given in the answers:
private static boolean isAWord(String token)
{
//check if the token is a word
}
How would you check that the token is a word? Would you .contains("\\s+") the string and check to see if it contains characters between them? But what about when you encounter a paragraph? I'm not sure how to go about this.
EDIT: I think I should've elaborated a bit more. Usually, you'd think a word would be something surrounded by " " but, for example, if the file contains a hyphen (which is also surrounded by a blank space), you'd want the isAWord() method to return false. How can I verify that something is actually a word and not punctuation?
Since the question wasn't entirely clear, I made two methods. First method consistsOfLetters just goes through the whole string and returns false if it has any numbers/symbols. This should be enough to determine if a token is word (if you don't mind if that words exists in dictionary or not).
public static boolean consistsOfLetters(String string) {
for(int i=0; i<string.length(); i++) {
if(string.charAt(i) == '.' && (i+1) == string.length() && string.length() != 1) break; // if last char of string is ., it is still word
if((string.toLowerCase().charAt(i) < 'a' || string.toLowerCase().charAt(i) > 'z')) return false;
} // toLowerCase is used to avoid having to compare it to A and Z
return true;
}
Second method helps us divide original String (for example a sentence of potentional words) based on " " character. When that is done, we go through every element there and check if it is a word. If it's not a word it returns false and skips the rest. If everything is fine, returns true.
public static boolean isThisAWord(String string) {
String[] array = string.split(" ");
for(int i = 0; i < array.length; i++) {
if(consistsOfLetters(array[i]) == false) return false;
}
return true;
}
Also, this might not work for English since English has apostrophes in words like "don't" so a bit of further tinkering is needed.
The Scanner in java splits string using his WHITESPACE_PATTERN by default, so splitting a string like "He's my friend" would result in an array like ["He's", "my", "friend"].
If that is sufficient, just remove that if clause and dont use that method.
If you want to make it to "He","is" instead of "He's", you need a different approach.
In short: The method works like verification check -> if the given token is not supposed to be in the result, then return false, true otherwise.
return token.matches("[\\pL\\pM]+('(s|nt))?");
matches requires the entire string to match.
This takes letters \pL and zero-length combining diacritical marks \pM (accents).
And possibly for English apostrophe, should you consider doesn't and let's one term (for instance for translation purposes).
You might also consider hyphens.
There are several single quotes and dashes.
Path path = Paths.get("..../x.txt");
Charset charset = Charset.defaultCharset();
String content = Files.readString(path, charset)
Pattern wordPattern = Pattern.compile("[\\pL\\pM]+");
Matcher m = wordPattern.matcher(content);
while (m.find()) {
String word = m.group(); ...
}

.replace to replace input letters with symbols

I want to make everything the user enters capitalized and certain letters to be replaced with numbers or symbols. Im trying to utilize .replace but something is not going right. Im not sure what im doing wrong?
public class Qbert
{
public static void main(String[] args)
{
//variables
String str;
//get input
Scanner kb = new Scanner(System.in);
System.out.print(" Please Enter a Word:");
//accept input
str = kb.nextLine();
System.out.print("" );
System.out.println(str.toUpperCase()//make all letters entered uppercase
//sort specific letters to make them corresponding number, letter, or symbol
+ str.replace("A,#")+ str.replaceChar("E","3")+ str.replaceChar ("G","6")
+ str.replaceChar("I","!")+ str.replaceChar("S","$")+ str.replaceChar ("T","7"));
}
}
In Java, Strings are immutable. This means that modifying a string will result in a new string. E.g.
str.replace("a", "b");
this will replace all the occurrences of 'a' to 'b' in a new string. Original string will remain unaffected. So, to apply the formatting on the actual string, we will have to write:
str = str.replace("a", "b");
Similarly, if we want to do multiple replacements then, we need to append replace calls together, e.g.
str = str.replace("a","b").replace("c", "d");
Going by this, if you want to perform the substitution, the last system.out in your code will be:
System.out.println(str.toUpperCase().replace("A","#").replace("E","3")
.replace("G","6").replace("I","!").replace("S","$").replace("T","7"));
String doesn't have a replaceChar method. You probably wanted to use method replace.
And String.replace() takes 2 arguments:
public String replace(CharSequence target, CharSequence replacement)
Replaces each substring of this string that matches the literal target
sequence with the specified literal replacement sequence. The
replacement proceeds from the beginning of the string to the end, for
example, replacing "aa" with "b" in the string "aaa" will result in
"ba" rather than "ab".
You have written str.replace("A,#")+... instead of str.replace("A","#")+..., and so on
One more thing - use a good IDE like Eclipse or Intellij IDEA, they will highlight the parts of your code where you have errors.
public static void main(String... args) {
// variables
String str;
// get input
Scanner kb = new Scanner(System.in);
System.out.print(" Please Enter a Word:");
// accept input
str = kb.nextLine();
System.out.print("");
System.out.println(str.toUpperCase()); // Upper Case
System.out.println(str.toUpperCase().replace("A", "#").replace("E", "3")
.replace("E", "3").replace("G", "6").replace("I", "!").replace("S", "$").replace("T", "7") );
}
This should work like you want it to. Hope you find this helpful.
As you want to make multiple changes to the same string, you just use
str.toUpperCase().replace().replace().... This means you are giving
the output of str.toUpperCase() to the first replace function and so
on...
System.out.println(str.toUpperCase()
.replace("A","#")
.replace("E","3")
.replace("G","6")
.replace("I","!")
.replace("S","$")
.replace("T","7"));

Looking for method to remove spaces on sides, change all letters to small with first letter as capital letter

I have been trying for a while to make a method which takes an user input and changes it so that potential spaces infront and after the text should be removed. I tried .trim() but doesnt seem to work on input strings with two words. also I didnt manage to make both first and second word have the first letter as Capital.
If user inputs the following string I want all separate words to have all small letters except for the first in the word. e.g: Long Jump
so if user inputs:
"LONG JuMP"
or
" LoNg JUMP "
change it to
"Long Jump"
private String normalisera(String s) {
return s.trim().substring(0,1).toUpperCase() + s.substring(1).toLowerCase();
}
I tried the method above but didnt work with two words, only if the input was one. It should work with both
To remove all spaces extra spaces you can do something like this
string = string.trim().replaceAll(" +", " ");
The above code will call trim to get rid of the spaces at the start and end, then use regex to replace everything that has 2 or more spaces with a single space.
To capitalize the first word, if you're using Apache's commons-lang, you can use WordUtils.capitalizeFully. Otherwise, you'll need to use a homebrewed solution.
Simply iterate through the String, and if the current character is a space, mark the next character to be uppercased. Otherwise, make it lowercase.
Split your problems into smaller ones:
You need to be able to:
iterate over all words and ignore all whitespaces (you can use Scanner#next for that)
edit single word into new form (create helper method like String changeWord(String){...})
create new String which will collect edited versions of each word (you can use StringBuilder or better StringJoiner with delimiter set as one space)
So your general solution can look something like:
public static String changeWord(String word) {
//code similar to your current solution
}
public static String changeText(String text) {
StringJoiner sj = new StringJoiner(" ");// space will be delimiter
try(Scanner sc = new Scanner(text)){
while (sc.hasNext()) {
sj.add(changeWord(sc.next()));
}
}
return sj.toString();
}
Since Strings are immutable and you cannot make in place changes you need to store it in a separate variable and then do your manipulations like this:
String s = " some output ";
String sTrimmed = s.trim();
System.out.println(s);
System.out.println(sTrimmed);
Change your code like this for the rest of your code as well.

How do I delete specific characters from a particular String in Java?

For example I'm extracting a text String from a text file and I need those words to form an array. However, when I do all that some words end with comma (,) or a full stop (.) or even have brackets attached to them (which is all perfectly normal).
What I want to do is to get rid of those characters. I've been trying to do that using those predefined String methods in Java but I just can't get around it.
Reassign the variable to a substring:
s = s.substring(0, s.length() - 1)
Also an alternative way of solving your problem: you might also want to consider using a StringTokenizer to read the file and set the delimiters to be the characters you don't want to be part of words.
Use:
String str = "whatever";
str = str.replaceAll("[,.]", "");
replaceAll takes a regular expression. This:
[,.]
...looks for each comma and/or period.
To remove the last character do as Mark Byers said
s = s.substring(0, s.length() - 1);
Additionally, another way to remove the characters you don't want would be to use the .replace(oldCharacter, newCharacter) method.
as in:
s = s.replace(",","");
and
s = s.replace(".","");
You can't modify a String in Java. They are immutable. All you can do is create a new string that is substring of the old string, minus the last character.
In some cases a StringBuffer might help you instead.
The best method is what Mark Byers explains:
s = s.substring(0, s.length() - 1)
For example, if we want to replace \ to space " " with ReplaceAll, it doesn't work fine
String.replaceAll("\\", "");
or
String.replaceAll("\\$", ""); //if it is a path
Note that the word boundaries also depend on the Locale. I think the best way to do it using standard java.text.BreakIterator. Here is an example from the java.sun.com tutorial.
import java.text.BreakIterator;
import java.util.Locale;
public static void main(String[] args) {
String text = "\n" +
"\n" +
"For example I'm extracting a text String from a text file and I need those words to form an array. However, when I do all that some words end with comma (,) or a full stop (.) or even have brackets attached to them (which is all perfectly normal).\n" +
"\n" +
"What I want to do is to get rid of those characters. I've been trying to do that using those predefined String methods in Java but I just can't get around it.\n" +
"\n" +
"Every help appreciated. Thanx";
BreakIterator wordIterator = BreakIterator.getWordInstance(Locale.getDefault());
extractWords(text, wordIterator);
}
static void extractWords(String target, BreakIterator wordIterator) {
wordIterator.setText(target);
int start = wordIterator.first();
int end = wordIterator.next();
while (end != BreakIterator.DONE) {
String word = target.substring(start, end);
if (Character.isLetterOrDigit(word.charAt(0))) {
System.out.println(word);
}
start = end;
end = wordIterator.next();
}
}
Source: http://java.sun.com/docs/books/tutorial/i18n/text/word.html
You can use replaceAll() method :
String.replaceAll(",", "");
String.replaceAll("\\.", "");
String.replaceAll("\\(", "");
etc..

Categories