Check if letter x is between two quotes - java

I'd like to check if some character is between 2 other chars.
For example, given the following String:
String myString = "Hello, my name is 'Tesda', and this is 'ASDfs'."
I want to check if the 'S' in "ASDfs" is between '' or not, also keeping in mind I want to check every '', not jump directly to the second ''.
I've tried a silly code (I'm not familiar with this at all, as I didn't need it until now), which is:
boolean isBetween;
if (!MyString.substring(MyString.indexOf("'"), MyString.indexOf("'")).contains("S"))
isBetween = true;
Well, this didn't work and I don't understand how to make it perfectly.
Also, I want to replace that S with another letter, but I want only between the '', not the one after "my name is", I thought about getting the index of the letter, if it's inside '', then replace that letter in that specific index, is that possible?
Using the provided answer, I've made the following code ( which why i posted this question for ) :
String NewText = "Hello, My NAme is 'Ba', i'm from 'LA' ";
boolean contains = false;
int indexOfS = -1;
String MyString_temp = NewText;
while (MyString_temp.length() >= 0) {
int first = MyString_temp.indexOf("\'");
if(first == -1)
{
break;
}
int second = MyString_temp.substring((first + 1)).indexOf("\'");
second = second + first + 1;
if(second == -1)
{
break;
}
contains = MyString_temp.substring(first,second).contains("A");
if (contains) {
break;
}
MyString_temp = MyString_temp.substring((second + 1));
}
Log.i("ResultTest","Index is: " + indexOfS + " - Text is: " + MyString_temp);
if(!contains){
Log.i("ResultTest", "Yes " + i);
Log.i("ResultTest","TeF: " +NewText.replace(NewText.substring(indexOfS,indexOfS+1),"Test"));
} else
Log.i("ResultTest", "No " + i);
Output
Index is: -1 - the text here ..
Failed to output, invalid index

Consider using regular expressions. Your example could be as simple as
MyString.matches("\'S\'");
EDIT: Updated answer for updated question: Your initial code block looked like it might have done the trick, however you must remember that indexOf() only returns the first occurence of what you need. This could work:
String MyString_temp = MyString;
String lookingFor = "S";
String separator = "\'";
boolean contains = false;
int indexOfLooking = -1;
while (MyString_temp.length() >= 0) {
int first = MyString_temp.indexOf(separator);
if(first == -1) {
break;
}
int second = MyString_temp.substring(first + 1).indexOf(separator);
second += first + 1;
if(second == -1) {
break;
}
indexOfLooking = MyString_temp.substring(first, second).indexOf(lookingFor);
contains = (indexOfLooking >= 0)
if (contains) {
break;
}
MyString_temp = MyString_temp.substring(second + 1);
}
After the while loop, contains has your answer, and indexOfLooking has the location of S.

With Apache Commons you can use the following method:
StringUtils.substringBetween(str, "'");
to get an String[] with all results use this:
StringUtils.substringsBetween(str, "'", "'");

Related

Adding some string before specific characters in Java

I want to add "OB" before every vowel.
Sample input: "THIS IS A TEST"
Sample output: "THOBIS OBIS OBA TOBEST"
I have no idea why my code doesn't work:
public static String obify(String test) {
int x = 0;
while (x != -1) {
if (test.charAt(x) == 'A' || test.charAt(x) == 'E' || test.charAt(x) == 'I' || test.charAt(x) == 'O' || test.charAt(x) == 'U') {
test = test.replace(test.substring(x, x+1), "ob" + test.substring(x, x+1));
x += 3;
} else {
x++;
}
if (x >= test.length() - 1) {
x = -1;
}
}
return test;
}
Perfect scenario for a simple regex
String foo = "hEllo what's up?";
String rep = foo.replaceAll("(?i)([aeiou])", "OB$1");
System.out.println(rep);
You should replace
test = test.replace(test.substring(x, x+1), "ob" + test.substring(x, x+1));
with
test = test.substring(0, x) +
"ob" +
test.substring(x, x + 1) +
test.substring(x + 1);
Your problem is that replace act on all occurrences of its first parameter.
When you have "THobIS IS A TEST" and try to replace marked letter you replace both "I" letter. After it you index points to completely wrong position before second "I". Sooner or later you get to it again and situation repeats.
Your problem is in replace call.
Documentaion tells that it replaces each substring with new one.
So your string grows infinitely:
after first replace it is: "THobIS obIS A TEST"
after next one is: "THobobIS obobIS A TEST"
then "THobobobIS obobobIS A TEST"
and so on...
If you change your line
test = test.replace(test.substring(x, x+1), "ob" + test.substring(x, x+1));
to
test = test.substring(0, x) + "ob" + test.substring(x);
it will do the work.
Also you can change while condition to x < test.length() and get rid of second if.
I think it is easier this way: For the word "GTREIS":
I basically take what was before and after the vowel(including the vowel) and attaching "OB"to the first part, attaching the remaining and finally replacing the original string with the modified one.
public static String obify(String s)
{
String inloc ="OB",aux="";
String start="";
int n=s.length();
int i=0;
while (i<n)
{
if(s.charAt(i)=='A'|| s.charAt(i)=='E' || s.charAt(i)=='I' || s.charAt(i)=='O'||s.charAt(i)=='U' ){
inloc ="OB";
start="";
aux=s.substring(i);//EIS
System.out.println(aux);
start=s.substring(0,i);//GTR
System.out.println(start);
start=start+inloc;//GTROB
System.out.println(start);
start=start+aux;
s=start;
i+=3;// here you have to jump over OBE for example and search the next vowel
n+=2;
} else {
i++;
}
}
return s;
}

Java's String.replaceAll not working [duplicate]

This question already has an answer here:
Why String.replaceAll() don't work on this String?
(1 answer)
Closed 8 years ago.
I'm building a string that represents a polynomial. I'm trying to replace all ^1 and x^0 with "" to simplify the output using the replaceAll method. However when I run the code, it does not detect any of the target strings.
public String toString() {
String output = "";
boolean isFirst = true;
for(Node current = head; current != null; current = current.next) {
if(isFirst) {
output += current.coefficient + "x^" + current.exponent;
isFirst = false;
}
else if(current.coefficient < 0)
output += " - " + current.coefficient*-1 + "x^" + current.exponent;
else
output += " + " + current.coefficient + "x^" + current.exponent;
}
output.replaceAll("x^0", "");
output.replaceAll("^1", "");
return output;
}
Strings are immutable. You cannot alter a String. As such, the replace and replaceAll methods return a new String. Here try this:
output = output.replaceAll("x^0", "");
output = output.replaceAll("^1", "");
Because Strings are immutable, any modifying operation returns a new string. Thus, you must save and work on with the function result:
output = output.replace(...)
Also, please take a look at the definite spec for allowed patterns: http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
The one point i want to call out is that a ^ at the start of a string anchors the pattern to the beginning of the string. You do not want that, so escape it: \^.
Anyway, you really want to remove the calls to replaceAll: "x^1" matches the beginning of "x^10"! Just don't include those substrings when you build your string.
double f = current.coefficient;
if(isFirst)
isFirst = false;
else if(f < 0) {
f = -f;
output += " - ";
} else
output += " + ";
output += f;
if(current.exponent == 1)
output += "x";
else if(current.exponent != 0)
Strings are immutable. If you look at the documentation, you'll see that every method that modify the content of a String returns a new one.
So you need to assign back the result of replaceAll to output.
output = output.replaceAll("x^0", "");

How do I find what's inbetween " " in an inputted string? [duplicate]

I'd like to retrieve whatever is in quotes that someone enters as a string, i'm assuming it's substring that I need but i'm not sure how.
When the user inputs a string mixed with words and numbers all separated by one space:
hey 110 say "I am not very good at Java" but " I can fish pretty well"
Then I want to be able to take the "I am not very good at Java" and the "I can fish pretty well" and print out what's inside the quotes so there can be multiple quotes in the string.
right now I have if( userInput=='"') then I do something with substring but i'm not sure what.
I can't use split, trim, tokenizer, regex or anything that would make this really easy unfortunatley.
it's all in this method where I try to identify if something in the string is a word, number or a quote:
public void set(String userInput)// method set returns void
{
num=0;// reset each variable so new input can be passed
String empty="";
String wordBuilder="";
userInput+=" ";
for(int index=0; index<userInput.length(); index++)// goes through each character in string
{
if(Character.isDigit(userInput.charAt(index)))// checks if character in the string is a digit
{
empty+=userInput.charAt(index);
}
else
{
if (Character.isLetter(userInput.charAt(index)))
{
wordBuilder+=userInput.charAt(index);
}
else
{
if(userInput.charAt(index)=='"')
{
String quote=(userInput.substring(index,);
}
}
//if it is then parse that character into an integer and assign it to num
num=Integer.parseInt(empty);
word=wordBuilder;
empty="";
wordBuilder="";
}
}
}
}
Thanks!
Try the next:
public static void main(String[] args) {
String input = "\"123\" hey 110 say \"I am not very good at Java\" but \" I can fish pretty well\"";
int indexQuote = -1;
boolean number = true;
String data = "";
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (Character.isWhitespace(ch)) {
if (data.length() > 0 && indexQuote == -1) {
if (number) {
System.out.println("It's a number: " + data);
} else {
System.out.println("It's a word: " + data);
}
// reset vars
number = true;
data = "";
} else if (indexQuote != -1) {
data += ch;
}
} else if (ch == '"') {
if (indexQuote == -1) {
number = false;
indexQuote = i;
} else {
System.out.println("It's a quote: " + data);
// reset vars
number = true;
data = "";
indexQuote = -1;
}
} else {
if (!Character.isDigit(ch)) {
number = false;
}
data += ch;
if (data.length() > 0 && i == input.length() - 1) {
if (number) {
System.out.println("It's a number: " + data);
} else {
System.out.println("It's a word: " + data);
}
}
}
}
}
Output:
It's a word: hey
It's a number: 110
It's a word: say
It's a quote: I am not very good at Java
It's a word: but
It's a quote: I can fish pretty well
I'm not sure if this quite what you are looking for, but it will strip down the quoted parts in steps...
String quote = "I say: \"I have something to say, \"It's better to burn out then fade away\"\" outloud...";
if (quote.contains("\"")) {
while (quote.contains("\"")) {
int startIndex = quote.indexOf("\"");
int endIndex = quote.lastIndexOf("\"");
quote = quote.substring(startIndex + 1, endIndex);
System.out.println(quote);
}
}
Which outputs...
I have something to say, "It's better to burn out then fade away"
It's better to burn out then fade away
Updated
I don't know if this is cheating or not...
String quote = "I say: \"I have something to say, \"It's better to burn out then fade away\"\" outloud...\"Just in case you don't believe me\"";
String[] split = quote.split("\"");
for (String value : split) {
System.out.println(value);
}
Which outputs...
I say:
I have something to say,
It's better to burn out then fade away
outloud...
Just in case you don't believe me
Updated
Okay, fake String#split
StringBuilder sb = new StringBuilder(quote.length());
for (int index = 0; index < quote.length(); index++) {
if (quote.charAt(index) == '"') {
System.out.println(sb);
sb.delete(0, sb.length());
} else {
sb.append(quote.charAt(index));
}
}
Updated
Okay, this is basically fake split with options...
String quote = "blah blah 123 \"hello\" 234 \"world\"";
boolean quoteOpen = false;
StringBuilder sb = new StringBuilder(quote.length());
for (int index = 0; index < quote.length(); index++) {
if (quote.charAt(index) == '"') {
if (quoteOpen) {
System.out.println("Quote: [" + sb.toString() + "]");
quoteOpen = false;
sb.delete(0, sb.length());
} else {
System.out.println("Text: [" + sb.toString() + "]");
sb.delete(0, sb.length());
quoteOpen = true;
}
} else {
sb.append(quote.charAt(index));
}
}
if (sb.length() > 0) {
if (quoteOpen) {
System.out.println("Quote: [" + sb.toString() + "]");
} else {
System.out.println("Text: [" + sb.toString() + "]");
}
}
Which generates...
Text: [blah blah 123 ]
Quote: [hello]
Text: [ 234 ]
Quote: [world]
Know, I don't know how you are storing the results. I would be tempted to create some basic classes which were capable of storing the String results and add them to a List so I could maintain the order and maybe use a flag of some kind to determine what type they are...
Iterate over the string and use a temporary int variable to store when the quoted string started. When you see that it ends, you can extract that substring and do what you want with it.
Use StringUtils.subStringBetween
public class MyTestSecond {
public static void main(String...args){
String a = "hey 110 say \"I am not very good at Java\"";
// Method 1
if(a.contains("\""))
System.out.println(a.substring(a.indexOf("\""),a.lastIndexOf("\"")+1));
//Method 2
String[] array = a.split(" ");
for(int i=0;i<array.length;i++){
if(array[i].startsWith("\""))
System.out.println(a.substring(a.indexOf("\""),a.lastIndexOf("\"")+1));
}
}
}
public String getNextQuote(int index, String sentence){
return sentence.substring(sentence.indexOf("\"", index + 1), sentence.indexOf("\"", index + 2));
}
usage: call the method with an index as parameter. This index resembles the index of the last " that you've encountered.
Afterwards, it will return everything between the next two quotes.

correct way of handling StringIndexOfBoundException

The below code throws me StringIndexOfBoundException
if (custom.getUser().equals("0") || custom.getUser().equals("")) {
vital.add(new Pair<String, String>("User", "-"));
} else {
vital.add(new Pair<String, String>("User", custom.user() + "F" + "\n" + custom.getName().subString(0,1));
}
Displaying the first character of the String. The below code is working fine, but i am not sure whether its the correct way of doing it.
String name = "";
if (custom.getUser().equals("0") || custom.getUser().equals("")) {
vital.add(new Pair<String, String>("User", "-"));
} else if (!custom.getName().equals("")) {
name = custom.getName().substring(0, 1);
} else {
vital.add(new Pair<String, String>("User", custom.user() + "F" + "\n" + name));
}
First, from where do you get the exception?
custom.getName().subString(0,1) throws a StringIndexOfBoundException only if custom.getName() is empty. But if it's empty, the code will not enter the else branch, so you can't be getting the exception.
Second, the second way is not equivalent to the first: if custom.getName() is neither empty nor "0" nothing is added to vital.
I feel this is an improvement:
if (custom.getUser().equals("0") || custom.getUser().isEmpty()) {
vital.add(new Pair < String, String > ("User", "-"));
} else {
// limit scope of variable to else-branch
String name = "";
// check empty string with isEmpty
if (!custom.getName().isEmpty()) {
name = custom.getName().substring(0, 1);
}
// add a new Pair in any case
vital.add(new Pair < String, String >
("User", custom.user() + "F" + "\n" + name));
}
You've just got a logic error in the first block. You can enter the block with an empty string (custom.getName().equals("")), which means that custom.getName().length() == 0. So when you try to get the first character with substring(0,1) it throws a StringIndexOfBoundException. Just change the conditional to something like this:
if (custom.getUser().equals("0") || custom.getName().length() > 0) {
In the else if condition you need to check if the string "custom.getName().length() >= 2".

Storing StringBuffer

I have a StringBuffer in my Class which deletes certain characters if the conditions are met in the IF statement and prints the statement. However, this could be repeated many times. If the second condition is met, the first statement will print out WITHOUT the characters being deleted.
Is there a way around this? Below is my code.
if (status == 1 && item == item1[1]){
item1[1] = "*";
w = sb1.append(item1[1]+"["+item2[1]+"] ");
sb1.delete(1,4);
}else if (status == 1 && item == item1[2]){
item1[2] = "*";
x = sb1.append(item1[2]+"["+item2[2]+"] ");
sb1.delete(1,4);
}else if(status == 1 && item == item1[3]){
item1[3] = "*";
y = sb1.append(item1[3]+"["+item2[3]+"] ");
sb1.delete(1,4);
}
return w.toString()+x.toString()+y.toString()+z.toString();
What i'm trying to achieve is the following:
I have a toString which is made up of:
item1[1]+"["item2[1]"] "+item1[2]+" ["+tem2[2]+"]"
I want to do this:
if item1 is marked as taken, it will be changed to "*" and remove the item2[1] and the [ ] around it and then return it as:
eg: item1[2] = x
item2[2] = 1
* x[1]
( * used to be item1[1] )
but if the loops passes through again, my current class does this:
*[] *[1]
i want it to be:
* *
When the loop is complete
A general problem: item looks like a String, item[] like a String[]. Do not use == with Strings, it will produce unexpected result occasionally. Use equals() instead:
if (status == 1 && item.equals(item1[1])) {
Use this pattern for the other conditional checks too.
(and add a test/handler for item == null which now would be necessary)
Another improvement: replace StringBuffer with StringBuilder and don't concatenate Strings while passing them to append. Not to correct an error, but to give better performance:
w = sb1.append(item1[1]).append("[").append(item2[1]).append("] ");
Your code looks suspicious. Lets pull out the 3-times test whether 'status == 1' (is there a hidden boolean in the variable, which tries to come out?). And put some fresh air between the tokens, to make the job for the eye more easy to split them:
if (status == 1)
{
if (item.equals (item1[1]))
{
item1[1] = "*";
w = sb1.append (item1[1] + "[" + item2[1] + "] ");
sb1.delete (1, 4);
}
else if (item.equals (item1[2]))
{
item1[2] = "*";
x = sb1.append (item1[2] + "[" + item2[2] + "] ");
sb1.delete (1, 4);
}
else if (item.equals (item1[3]))
{
item1[3] = "*";
y = sb1.append (item1[3] + "[" + item2[3] + "] ");
sb1.delete (1, 4);
}
}
return (w.append (x). append (y). append (z)).toString ();
//
Looks like 3times the same statement, just iterating through 1,2,3 and w,x,y. I used append in the last line too, and just put the 'toString ()' on the end result.
Let's make a loop from the 3 statements:
if (status == 1)
{
for (int i = 1; i < 4; ++i)
{
if (item.equals (item1[i]))
{
item1[i] = "*";
w = sb1.append (item1[i] + "[" + item2[i] + "] ");
sb1.delete (1, 4);
}
}
}
return (w.append (w). append (w). append (w)).toString ();
Depending on your code, sideeffects, threads and so on, this might result in something different, but I don't think so. Especially I don't know what w,x,y are by default, if not assigned in that code part. And the code looks, as if item is either equals item1[1] or item1[2] or item1[3] exclusively. But it might be equal to all 3, and then the loop will hit 3 times instead of 1 time.
However, item1/item2 is a code smell. It smells like 2-dim-array or not well thought of object orientation (item.color, item.name or something like that).

Categories

Resources