Java String.split error - java

My method successfully takes a binary expression tree and turns it into prefix, postfix, and infix notation. However, due to the accuracy of the final string, it must be exactly equal.
So before I return my output, I will run a method to quickly edit that output to remove any flaws.
(* (+ 8 4) (- 7 (/ 6 3))) ===> (*(+ 8 4)(- 7(/ 6 3)))
((8 4 +) (7 (6 3 /) -) ) =====> ((8 4 +)(7 (6 3 /)-))
What needs to be changed, are the spacing inbetween parens. My goal was to find all cases of a string, remove them, and reinput in the string without spaces.
underlines are extra spaces
(*(+ 8 4)(- 7_(/ 6 3)))
My code was supposted to be String.split(") ("); but error signs... unmatched closing ')')(???
public String antibullshiter(String out) {
out = out.replaceFirst(") (", "X"); //edited
String[] parts = out.split("X");
String part1 = parts[0];
String part2 = parts[1];
part1 = part1 + ")";
part2 = part2 + "(";
out = part1 + part2;
return out;}
How do I harness the power of String.split()?
edit: thanks guys, but I realized I just had to deal with the primary method in itself

As mentioned in the other answers / comments, String.split takes a pattern string (regular expression), and that's why you're getting the unmatched parenthesis error. You can use the Pattern.quote method to get the pattern string that would match your string literal:
yourString.split(java.util.regex.Pattern.quote(") ("));

As, String is immutable. To got the changes of replaceFirst method, you need to re-assign with out. Also you need to skip the Meta Character.
out=out.replaceFirst("\\)\\s*\\(", "X");

Try this. It replaces the string.
out.replaceFirst("\\) \\(", "X");

You can use this regular expression to remove spaces surrounding parenthesis:
out=out.replaceAll("\\s*([()])\\s*", "$1");

Use s.replaceAll("(?<=\\))\\s(?=\\()","") to remove the spaces
the error is because the string is a regex string, and parenteses must be escaped with double backslash ("\\(") otherwise they have special meaning.
Edit: use s.replaceAll("(?<=\\))\\s+(?=\\()","") for multiple spaces

Related

String Split method not Giving desired results [duplicate]

This question already has answers here:
Java string split with "." (dot) [duplicate]
(4 answers)
Closed 7 years ago.
I am trying to use Split method of String in java I have example like this.
String number = Math.random() * 100 + "";
System.out.println("Number is : " + number);
String[] seprate = number.split(".");
System.out.println(seprate.length);
it should give me 2 Stack of array i mean 2 array element if value is like e.g. 67.90512897385857
but its not giving value like that
String number = Math.random() * 100 + "";
System.out.println("Number is : " + number);
String[] seprate = number.split(".");
System.out.println(seprate.length);
System.out.println(seprate[1]);
its giving arrayindexoutbound exception.
Someone give idea why its giving like that?
The String#split method takes a regular expression.
The "." in there means any character.
Escape your "." as such to signal a literal dot: number.split("\\.").
As Pieter De Bie points out, using java.util.regex.Pattern to safely escape your literals when passing literals to an argument that is going to be interpreted as a regular expression will help you a good deal.
In this case, you could use: number.split(Pattern.quote("."))
You need to escape the dot. The split method takes a regular expression. From the docs:
Parameters:regex the delimiting regular expression
String[] seprate = number.split("\\.");
Split works with regex and you should use like this
number.split("\\.")
Pay attention to the documentation:
public String[] split(String regex)
Splits this string around matches of the given regular expression.
In a regular expression, . is any character (except newlines, usually).
So you are splitting at every character.
If you want to match only a dot, "\\." will work.
Double f = Math.random() * 100;
String number = String.valueOf(f);
System.out.println("Number is : " + number);
String[] seprate = number.split("\\.");
System.out.println(seprate.length);
Please use this link for ur question.
The split() method in Java does not work on a dot (.)

replace a String (in some cases) in java

if i have for example String a = "8sin(30)+sin(40) + 3sin(30)"
String b = a;how I can replace only the first "sin" and the third for "*sin", mantaining the second "sin" the same?
in other word, how I can replace part of a string only in specific cases?
If you want to replace sin which have number before it you can use something like
yourString = yourString.replaceAll("(\\d+)sin","$1*sin");
replaceAll uses regular expression which represents
\\d+ string build from one or more digit characters (like 0, 12, 321...) - we will place this number in group 1
sin literal.
In replacement we are reusing match from group 1 via $1
Demo:
String a = "8sin(30)+sin(40) + 3sin(30)";
System.out.println(a.replaceAll("(\\d)+sin","$1*sin"));
Output: 8*sin(30)+sin(40) + 3*sin(30)
You can also use look-behind to check if before sin there is any digit
String a = "8sin(30)+sin(40) + 3sin(30)";
System.out.println(a.replaceAll("(?<=\\d)sin","*sin"));
You are probably looking for the replaceFirst(String regex, String replacement) method of String.
You can use below regex:
[0-9]+sin
Demo
b=b.replaceFirst("[0-9]+sin","*sin");
Also you can use the substring(int beginIndex) method.

String.split() not working with "[]" [duplicate]

This question already has answers here:
Why can't I split a string with the dollar sign?
(6 answers)
Closed 7 years ago.
I have a IPv6 string
String str = "demo1 26:11:d0a2:f020:0:0:0:a3:2123 demo2";
String searchString = "26:11:d0a2:f020:0:0:0:a3:2123";
When i use str.split(searchString) code returns
["demo1 ", " demo2"]
Which is fine but when i use:
String str = "demo1 [26:11:d0a2:f020:0:0:0:a3]:2123 demo2";
String searchString = "[26:11:d0a2:f020:0:0:0:a3]:2123";
and do str.split(searchString) it reutrns
[demo1 [26:11:d0a2:f020:0:0:0:a3]:2123 demo2]
Which is wrong i guess , can some one tell why I am getting this sort of output?
Since split function takes a regex as parameter, you need to escape those brackets otherwise this [26:11:d0a2:f020:0:0:0:a3] would match a single character only.
String searchString = "\\[26:11:d0a2:f020:0:0:0:a3\\]:2123";
str.split(searchString);
It is happening because split(String str) take regex pattern string as argument. And that string will be used as regex pattern to match all the delimiter with this pattern.
In your regex pattern you are providing character sets in [].
To make it work your way you will have to use this regex pattern string :
\[26:11:d0a2:f020:0:0:0:a3\]:2123
i.e. in java :
String searchString = "\\[26:11:d0a2:f020:0:0:0:a3\\]:2123";
I hope you are familiar with the string regexs. In java, the regex [abc] means match with a OR b OR c I encourage you to escape your square brackets try:
String str = "demo1 [26:11:d0a2:f020:0:0:0:a3]:2123 demo2";
String searchString = "\\[26:11:d0a2:f020:0:0:0:a3\\]:2123";
You have to use an escape sequence for some special characters. Use \\[ ... \\] in the searchString variable.

Converting a String representing a mathemetical expression into an array

I want to convert a String such as 1+40.2+(2) into a String array [1, +, 40.2, +, (, 2, )] in order to use it as a parameter for a Shunting Yard algorithm in my Calculator class.
The input will be entered without spaces, so I can't just use input.split("\\s+"). I have come up with a long process involving ArrayLists, StringBuilders, and stacks, but I was wondering if there was an easier way to do this.
input.split("") won't work, since it would return [1, +, 4, 0, ., 2, +, (, 2, )]. This is actually the starting point of my current process, and I can post the pseudocode for it, if anyone is interested (although I'm having problems actually implementing my pseudocode).
Any advice or help is appreciated. Thanks!
I really like the first answer, but if you want to try using Regex as suggested in second comment, here's a Regex that will match each element of your equation one by one so you can append to your list. Note that it assumes that all of the string consists of are decimal point numbers, operators, and parenthesis.
[0-9\.]+|[+\-*/]|[()]
Note that in character classes, any character except ^-]\ is a literal so that's why the character classes look a bit funny. To construct the corresponding Java pattern, use
Pattern.compile("[0-9\\.]+|[+\\-*/]|[()]")
Example:
String s = "1+40.2+(2)";
Pattern p = Pattern.compile("[0-9\\.]+|[+\\-*/]|[()]");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println(m.group());
}
Output:
1
+
40.2
+
(
2
)
The replaceAll string method should be able to help you. Use this to surround the tokens you want to pull out with a special dividing character (I arbitrarily chose ':', but any character/string you're confident won't actually be in the input will work). Then you can split on that character.
String s = "1+40.2+(2)";
String dividingToken = ":";
String[] sSplit = s.replaceAll("\\+", dividingToken + "+" + dividingToken)
.replaceAll("\\(", dividingToken + "(" + dividingToken)
.replaceAll("\\)", dividingToken + ")" + dividingToken)
.split(dividingToken);
for(String str: sSplit){
System.out.println(str);
}
Output:
1
+
40.2
+
(
2
)
You could easily loop .replaceAll over an array of tokens (["+", "-", "*", ...]) that you want to split up. Just remember to add "//" before it in replace all because many of them have special regex meaning, whereas you actually want to match "+".

Difference between String replace() and replaceAll()

What's the difference between java.lang.String 's replace() and replaceAll() methods,
other than later uses regex? For simple substitutions like, replace . with / ,
is there any difference?
In java.lang.String, the replace method either takes a pair of char's or a pair of CharSequence's (of which String is a subclass, so it'll happily take a pair of String's). The replace method will replace all occurrences of a char or CharSequence. On the other hand, the first String arguments of replaceFirst and replaceAll are regular expressions (regex). Using the wrong function can lead to subtle bugs.
Q: What's the difference between the java.lang.String methods replace() and replaceAll(), other than that the latter uses regex.
A: Just the regex. They both replace all :)
http://docs.oracle.com/javase/8/docs/api/java/lang/String.html
PS:
There's also a replaceFirst() (which takes a regex)
Both replace() and replaceAll() replace all occurrences in the String.
Examples
I always find examples helpful to understand the differences.
replace()
Use replace() if you just want to replace some char with another char or some String with another String (actually CharSequence).
Example 1
Replace all occurrences of the character x with o.
String myString = "__x___x___x_x____xx_";
char oldChar = 'x';
char newChar = 'o';
String newString = myString.replace(oldChar, newChar);
// __o___o___o_o____oo_
Example 2
Replace all occurrences of the string fish with sheep.
String myString = "one fish, two fish, three fish";
String target = "fish";
String replacement = "sheep";
String newString = myString.replace(target, replacement);
// one sheep, two sheep, three sheep
replaceAll()
Use replaceAll() if you want to use a regular expression pattern.
Example 3
Replace any number with an x.
String myString = "__1_6____3__6_345____0";
String regex = "\\d";
String replacement = "x";
String newString = myString.replaceAll(regex, replacement);
// __x_x____x__x_xxx____x
Example 4
Remove all whitespace.
String myString = " Horse Cow\n\n \r Camel \t\t Sheep \n Goat ";
String regex = "\\s";
String replacement = "";
String newString = myString.replaceAll(regex, replacement);
// HorseCowCamelSheepGoat
See also
Documentation
replace(char oldChar, char newChar)
replace(CharSequence target, CharSequence replacement)
replaceAll(String regex, String replacement)
replaceFirst(String regex, String replacement)
Regular Expressions
Tutorial
List of patterns
The replace() method is overloaded to accept both a primitive char and a CharSequence as arguments.
Now as far as the performance is concerned, the replace() method is a bit faster than replaceAll() because the latter first compiles the regex pattern and then matches before finally replacing whereas the former simply matches for the provided argument and replaces.
Since we know the regex pattern matching is a bit more complex and consequently slower, then preferring replace() over replaceAll() is suggested whenever possible.
For example, for simple substitutions like you mentioned, it is better to use:
replace('.', '\\');
instead of:
replaceAll("\\.", "\\\\");
Note: the above conversion method arguments are system-dependent.
Both replace() and replaceAll() accepts two arguments and replaces all occurrences of the first substring(first argument) in a string with the second substring (second argument).
replace() accepts a pair of char or charsequence and replaceAll() accepts a pair of regex.
It is not true that replace() works faster than replaceAll() since both uses the same code in its implementation
Pattern.compile(regex).matcher(this).replaceAll(replacement);
Now the question is when to use replace and when to use replaceAll().
When you want to replace a substring with another substring regardless of its place of occurrence in the string use replace(). But if you have some particular preference or condition like replace only those substrings at the beginning or end of a string use replaceAll(). Here are some examples to prove my point:
String str = new String("==qwerty==").replaceAll("^==", "?"); \\str: "?qwerty=="
String str = new String("==qwerty==").replaceAll("==$", "?"); \\str: "==qwerty?"
String str = new String("===qwerty==").replaceAll("(=)+", "?"); \\str: "?qwerty?"
To throw more light with an example into how both are going to work for below code:
public static void main(String[] args)
{
String s = "My\\s aaab\\s is\\s aaab\\s name";
String s1 = s.replace("\\s", "c");
System.out.println(s1);
String s2 = s.replaceAll("\\s", "c");
System.out.println(s2);
}
Output:
Myc aaabc isc aaabc name
My\scaaab\scis\scaaab\scname
Explanation
s.replace replaces "\\s" sequence of characters with c. Hence, the output in first line.
s.replaceAll considers \\s as a regex rather(equivalent to space) and replaces spaces with c. \\s in String s is escaped with first \ encountered and becomes \s.
Intellij Idea is smart enough to notify you of the usage as well. If you take a closer look at below image, you will see the difference in interpretation by Intellij idea for replace and replaceAll usage.
String replace(char oldChar, char newChar)
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
String replaceAll(String regex, String replacement
Replaces each substring of this string that matches the given regular expression with the given replacement.
Old thread I know but I am sort of new to Java and discover one of it's strange things. I have used String.replaceAll() but get unpredictable results.
Something like this mess up the string:
sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");
So I designed this function to get around the weird problem:
//String.replaceAll does not work OK, that's why this function is here
public String strReplace( String s1, String s2, String s )
{
if((( s == null ) || (s.length() == 0 )) || (( s1 == null ) || (s1.length() == 0 )))
{ return s; }
while( (s != null) && (s.indexOf( s1 ) >= 0) )
{ s = s.replace( s1, s2 ); }
return s;
}
Which make you able to do:
sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
As alluded to in wickeD's answer, with replaceAll the replacement string is handled differently between replace and replaceAll. I expected a[3] and a[4] to have the same value, but they are different.
public static void main(String[] args) {
String[] a = new String[5];
a[0] = "\\";
a[1] = "X";
a[2] = a[0] + a[1];
a[3] = a[1].replaceAll("X", a[0] + "X");
a[4] = a[1].replace("X", a[0] + "X");
for (String s : a) {
System.out.println(s + "\t" + s.length());
}
}
The output of this is:
\ 1
X 1
\X 2
X 1
\X 2
This is different from perl where the replacement does not require the extra level of escaping:
#!/bin/perl
$esc = "\\";
$s = "X";
$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";
which prints
\X 2
This can be quite a nuisance, as when trying to use the value returned by java.sql.DatabaseMetaData.getSearchStringEscape() with replaceAll().
From Java 9 there is some optimizations in replace method.
In Java 8 it uses a regex.
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
From Java 9 and on.
And Stringlatin implementation.
Which perform way better.
https://medium.com/madhash/composite-pattern-in-a-nutshell-ad1bf78479cc?source=post_internal_links---------2------------------
replace() method doesn't uses regex pattern whereas replaceAll() method uses regex pattern. So replace() performs faster than replaceAll().
To add to the already selected "Best Answer" (and others that are just as good like Suragch's), String.replace() is constrained by replacing characters that are sequential (thus taking CharSequence). However, String.replaceAll() is not constrained by replacing sequential characters only. You could replace non-sequential characters as well as long as your regular expression is constructed in such a way.
Also (most importantly and painfully obvious), replace() can only replace literal values; whereas replaceAll can replace 'like' sequences (not necessarily identical).
replace works on char data type but replaceAll works on String datatype and both replace the all occurrences of first argument with second argument.

Categories