Splitting strings like push1234 in java - java

So, please bear with me as I have a long question here, I have some code in java that is using an array list to implement a stack. I need to be able to enter the command "push" to add stuff to the stack. However my problem is that it has to be in the format pushSTUFF.
Where the "STUFF" is anything, upper case, lower case, string, int, etc.. The way I've been trying to implement this is with the string split method where PUSH is the delimiter. Then the command is passed to a switch case.
I quickly realized that the split gets discarded, at least as far as I can tell, and that the switch case is getting pushSTUFF not push as the case input.
In contemplating this problem I came up with a couple of ways I could do this. I just don't know if they are possible or how to do them.
So,
Is there a way to split a string like pushSTUFF and keep both parts (the push and the STUFF)
Is there a way to split, from a string, something of unknown length or contents (since I don't know what the user will input the STUFF is unknown)
Is there a way to tell the switch case to look for the pushSTUFF as opposed to just push (again because STUFF is unknown).
Are any of these even possible to do? If so what would you recommend?
I'm sure there are better ways but as I'm still learning java these seemed like the best for right now. Also I didn't post any code because I didn't feel it was necessary to the question. I will post some if you need it though. Just ask and I will be happy to oblige.
(tl;dr) Is it possible to do any of 1, 2, or 3 above and if so how?
Thanks in advance.

Instead of splitting the strings, you can use regular expressions with groups and iterate over the matching parts of it (as you saw, the split character(s) get discarded).
For #1, you could do something like (pseudocode):
regex = (push)(.*)
stuff = groups[1]
That should also cover #2 since it will match all characters after the push.
I'm not entirely sure what you're asking in #3.
There is a regex tutorial here if you're not familiar with java regular expressions.
You can also take a look at the StringTokenizer, which has an option to keep delimiters.

If the format will always be push*SOMETHING* why aren't you using String.substring()?
You can do:
String something = "pushSTUFF".substring(4);
This way, you will always get whatever is behind push.
I really don't understand what you are trying to achieve without seeing the actual code, but your problem seems simple enough to be solved this way.

Use .indexOf and find push:
public class splitstring {
public static void main(String[] args){
String tosplit, part1, part2 = new String();
int ind = 0;
tosplit = "push1234";
ind = tosplit.indexOf("push");
part1 = tosplit.substring(ind,ind + 4);
part2 = tosplit.substring(ind + 4, tosplit.length());
}
}

You can search for any Uppercase letter and use String.substring(...)
Find if first character in a string is upper case, Java

Related

Why is my String array length 3 instead of 2?

I'm trying to understand regex. I wanted to make a String[] using split to show me how many letters are in a given string expression?
import java.util.*;
import java.io.*;
public class Main {
public static String simpleSymbols(String str) {
String result = "";
String[] alpha = str.split("[\\+\\w\\+]");
int alphaLength = alpha.length;
// System.out.print(alphaLength);
String[] charCount = str.split("[a-z]");
int charCountLength = charCount.length;
System.out.println(charCountLength);
}
}
My input string is "+d+=3=+s+". I split the string to count the number of letters in string. The array length should be two but I'm getting three. Also, I'm trying to make a regex to check the pattern +b+, with b being any letter in the alphabet? Is that correct?
So, a few things pop out to me:
First, your regex looks correct. If you're ever worried about how your regex will perform, you can use https://regexr.com/ to check it out. Just put your regex on the top and enter your string in the bottom to see if it is matching correctly
Second, upon close inspection, I see you're using the split function. While it is convenient for quickly splitting strings, you need to be careful as to what you are splitting on. In this case, you're removing all of the strings that you were initially looking at, which would make it impossible to find. If you print it out, you would notice that the following shows (for an input string of +d+=3=+s+):
+
+=3=+
+
Which shows that you accidentally cut out what you were looking to find in the first place. Now, there are several ways of fixing this, depending on what your criteria is.
Now, if what you wanted was just to separate on all +s and it doesn't matter that you find only what is directly bounded by +s, then split works awesome. Just do str.split("+"), and this will return you a list of the following (for +d+=3=+s+):
d
=3=
s
However, you can see that this poses a few problems. First, it doesn't strip out the =3= that we don't want, and second, it does not truly give us values that are surrounded by a +_+ format, where the underscore represents the string/char you're looking for.
Seeing as you're using +w, you intend to find words that are surrounded by +s. However, if you're just looking to find one character, I would suggest using another like [a-z] or [a-zA-Z] to be more specific. However, if you want to find multiple alphabetical characters, your pattern is fine. You can also add a * (0 or more) or a + (1 or more) at the end of the pattern to dictate what exactly you're looking for.
I won't give you the answer outright, but I'll give you a clue as to what to move towards. Try using a pattern and a matcher to find the regex that you listed above and then if you find a match, make sure to store it somewhere :)
Also, for future reference, you should always start a function name with a lower case, at least in Java. Only constants and class names should start in a capital :)
I am trying to use split to count the number of letters in that string. The array length should be two, but I'm getting three.
The regex in the split functions is used as delimiters and will not be shown in results. In your case "str.split([a-z])" means using alphabets as delimiters to separate your input string, which makes three substrings "(+)|d|(+=3=+)|s|(+)".
If you really want to count the number of letters using "split", use 'str.split("[^a-z]")'. But I would recommend using "java.util.regex.Matcher.find()" in order to find out all letters.
Also, I'm trying to make a regex to check the pattern +b+, with b being any letter in the alphabet? Is that correct?
Similarly, check the functions in "java.util.regex.Matcher".

Regex to match a fixed sub string in a String

I am trying to write a regular expression to verify the presence of a specific number in a fixed position in a String.
String: 109300300330066611111111100000000017000656052086116020170111Name 1
Number to find: 111111111 (Staring from position 17)
I have written the following regular expression:
^.{16}(?<Ones>111111111)(.*)
My understanding is:
Let first 16 characters be whatever they are
Use the Named Capturing Group to grab the specific word
Let the rest of the characters be whatever they are
I am new to regex, is there any issue with the above approach?
Can it be done in other/better way?
I am using Java 8.
Without more details of why you're doing what you're doing, there's just one possible improvement I can see. You repeated any character 16 times at the beginning of the string rather than writing out 16 .s, which is nice and readable, but then, it would be nice to do the same for the repeated 1s:
^.{16}(?<Ones>1{9})(.*)
Otherwise, the string of 1s is hard to understand without the coder manually counting how many there are in the regex.
If you want to hard-code the ones and you know the starting position and you just wnat to know if it is there, using a regex seems unnecessary. you can use this:
String s = "109300300330066611111111100000000017000656052086116020170111Name 1";
if (s.indexOf("111111111").equals(16) doSomething();
Another possible solution without regex:
if(s.substring(16,25).equals("111111111") doSomething();
Otherwise your regex looks good.

String.split() returns an array with an additional empty value

I'm working on a piece of code where I've to split a string into individual parts. The basic logic flow of my code is, the numbers below on the LHS, i.e 1, 2 and 3 are ids of an object. Once I split them, I'd use these ids, get the respective value and replace the ids in the below String with its respective values. The string that I have is as follow -
String str = "(1+2+3)>100";
I've used the following code for splitting the string -
String[] arraySplit = str.split("\\>|\\<|\\=");
String[] finalArray = arraySplit[0].split("\\(|\\)|\\+|\\-|\\*");
Now the arrays that I get are as such -
arraySplit = [(1+2+3), >100];
finalArray = [, 1, 2, 3];
So, after the string is split, I'd replace the string with the values, i.e the string would now be, (20+45+50)>100 where 20, 45 and 50 are the respective values. (this string would then be used in SpEL to evaluate the formula)
I'm almost there, just that I'm getting an empty element at the first position. Is there a way to not get the empty element in the second array, i.e finalArray? Doing some research on this, I'm guessing it is splitting the string (1+2+3) and taking an empty element as a part of the string.
If this is the thing, then is there any other method apart from String.split() that would give me the same result?
Edit -
Here, (1+2+3)>100 is just an example. The round braces are part of a formula, and the string could also be as ((1+2+3)*(5-2))>100.
Edit 2 -
After splitting this String and doing some code over it, I'm goind to use this string in SpEL. So if there's a better solution by directly using SpEL then also it would be great.
Also, currently I'm using the syntax of the formula as such - (1+2+3) * 4>100 but if there's a way out by changing the formula syntax a bit then that would also be helpful, e.g replacing the formula by - ({#1}+{#2}+{#3}) *
{#4}>100, in this case I'd get the variable using {# as the variable and get the numbers.
I hope this part is clear.
Edit 3 -
Just in case, SpEL is also there in my project although I don't have much idea on it, so if there's a better solution using SpEL then its more than welcome. The basic logic of the question is written at the starting of the question in bold.
If you take a look at the split(String regex, int limit)(emphasis is mine):
When there is a positive-width match at the beginning of this string then an empty leading substring is included at the beginning of the resulting array.
Thus, you can specify 0 as limit param:
If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.
If you keep things really simple, you may be able to get away with using a combination of regular expressions and string operations like split and replace.
However, it looks to me like you'd be better off writing a simple parser using ANTLR.
Take a look at Parsing an arithmetic expression and building a tree from it in Java and https://theantlrguy.atlassian.net/wiki/display/ANTLR3/Five+minute+introduction+to+ANTLR+3
Edit: I haven't used ANTLR in a while - it's now up to version 4, and there may be some significant differences, so make sure that you check the documentation for that version.

Java regex insert single character between two patterns

Let's say I have for example a string...
2*Math.sqrt(5265+Math.sin(53*2*Math.exp(3+(5+5)*3
I'd like to get following string by using regex...2*Math.sqrt(5265)+Math.sin(53)*2*Math.exp(3)+(5+5)*3
So if I am right I just need to insert ) into a string, right between an unknown-length number [0-9] and a operator, which can be one of * - / +.
Furthermore, I'd like to know if (how?) it is possible to get an extended version supporting both Math.pow and above examples. At the moment, I'm using only single-argument Math.* methods, which are OK with above not-implemented-yet solution. But what if I'd like to use Math.pow? So let's just say, that input string is for example...
2*Math.sqrt(5265+Math.sin(53*2*Math.exp(3+(5+5)*3*24Math.pow(3*5*Math.sin(5
And the output I wish looks like... 2*Math.sqrt(5265)+Math.sin(53)*2*Math.exp(3)+(5+5)*3*Math.pow(24,3)*5*Math.sin(5)
(I am asking, because then I'd like to pass edited strings to ScriptEngine eval.)
Edit
Yes, sorry, I haven't made myself clear. I actually don't care whether I get *2* or *(2)* because ScriptEngine's method eval takes both and at the moment I can't imagine any problems with these forms. Second, I'd like to get general solution with every single operator * - / +, strings mentioned above were just examples. I'll try to be more specific. So now ignoring the second Math.pow part, the main string, let's call it A, basically consists of one or more strings in the form that looks like this... QWMath.[a-z](XWY, where Q is [0-9], W is one of * - / + and X is again [0-9].QW and Y are both optional, where Y is either another A string or [0-9], which is connected to the previous string with a W operator.
But it seems, that femtoRgon's solution replacing (Math\.[a-z]+\(\d+) with $1) is OK.
For the Math.pow part: The femtoRgon's solution replacing (\d+)(Math.pow\()(\d+) with $2$1$3) is fine too except missing , in $2$1$3). It should be $2$1,$3) and second, with replace method I had to add aditional backslashes: (\\d+)(Math.pow\\()(\\d+), same with (Math\.[a-z]+\(\d+)...
So in the end I it seems It's quite sufficient to do something like this...
String evalString = "2*Math.sqrt(5265+Math.sin(53*2*Math.exp(3+(5+5)*3*2554Math.pow(451";
String firstPattern = "(\\d+)(Math.pow\\()(\\d+)";
String secondPattern = "(Math\\.[a-z]+\\(\\d+)";
String tempString = evalString.replaceAll(firstPattern, "$2$1,$3)");
System.out.println(tempString.replaceAll(secondPattern, "$1"));
...maybe it can be much shorter. Of course it's not the exact solution, but the rest is just a cosmetic detail now.
By your explanation, your first case sounds simple enough. Simply replace:
(\(\d*)
with
$1)
However, this will not produce your desired output, but insteead will give you:
2*Math.sqrt(5265)+Math.sin(53)*2*Math.exp(3)+(5)+5)*3
What is the logic that would prevent you transforming (5+5) in that way?
Perhaps you only want to perform this with function begining with Math.? In that case, you could try replacing:
(Math\.[a-z]+\(\d+)
with
$1)
Don't run it twice though. There is nothing stopping this from changing Math.pow(3) into Math.pow(3))
To transform 24Math.pow(3 in Math.pow(24,3), you could replace:
(\d+)(Math.pow\()(\d+)
with
$2$1$3)

How do I split a concatenated string into multiple floating point values?

I'm a begginer in java I have
packet=090209153038020734.0090209153039020734.0
like this I want to split this string and store into an array like two strings:
1) 090209153038020734.0
2) 090209153039020734.0
I have done like this:
String packetArray[] = packets.split(packets,Constants.SF);
Where:
Constants.SF=0x01.
But it won't work.
Please help me.
I'd think twice about using split since those are obviously fixed width fields.
I've seen them before on another question here (several in fact so I'm guessing this may be homework (or a popular data collection device :-)) and it's plain that the protocol is:
STX (0x01).
0x0f.
date (YYMMDD or DDMMYY).
time (HHMMSS).
0x02.
value (XXXXXX.X).
0x03.
0x04.
And, given that they're fixed width, you should probably just use substrings to get the information out.
The JavaDoc of String is helpful here: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html
You have your String packet;
String.indexOf(String) gives you a position of a special substring. your interested in the "." sign. So you write
int position = packet.indexOf(".")+1
+1 becuase you want the trailing decimal too. It will return something 20-ish and will be the last pos of the first number.
Then we use substring
String first = packet.substring(0,position) will give you everything up to the ".0"
String second = packet.substring(position-1) should give you everything starting after the ".0" and up to the end of the string.
Now if you want them explicitely into an array you can just put them there. The code as a whole - I may have some "off by one" -bugs.
int position = packet.indexOf(".")+1
String first = packet.substring(0,position)
String second = packet.substring(position-1)
String[] packetArray = new String[2];
packetArray[0] = first;
packetArray[1] = second;
String packetArray[] = packets.split("\u0001");
should work. You are using
public String[] split(String regex, int limit)
which is doing something else: It makes sure that split() returns an array with at most limit members (1 in this case, so you get what you ask for).
You need to read the Javadocs for the String.split() methods...you are calling the version of String.split() that takes a regular expression and a limit, but you are passing the string itself as the first parameter, which doesn't really make sense.
As Aaron Digulla mentioned, use the other version.
You don't say how you want to do the split. It could be based on a fixed length (number of characters) or you want one decimal place.
If the former you could do packetArray = new String[]{packet.substring(0, 20), packet.substring(21)};
int dotIndex = packets.indexOf('.');
packetArray = new String[]{packet.substring(0, dotIndex+2), packet.substring(dotIndex+2)};
Your solution confuses the regexp with the string.
split uses regular expressions as documented here. Your code seems to be trying to match the whole string Constants.SF = 0x01 times, which doesn't make much sense. If you know what char the boxes are then you can use something like {[^c]+cc} where c is the character of the box (i guess this is 0x01), to match each "packet".
I think you are trying to use it like the .net String.Split(...) function?

Categories