Java: Substring to arrray of Strings - java

I have this String:
Java 2 5 22 8
I want an Array of Strings with these values:
["2"; "5"; "22"; "8"]
Is there a way to use subString() method in order to do so, or should I take another approach?

Nevertheless how many spaces there are:
String str = "Java 5 22 8";
String[] arr =
str
.replaceAll("( )+"," ")
.replaceFirst("Java ", "")
.split(" ");
for (String a : arr) {
System.out.println(a);
}

After searching a bit on split and regex, I found the answer: line.split("[ ]{2,}")

You seen to be uninterested in "Java" prefix, so you can call substring and trim (to remove the spaces around the 4 numbers):
line.substring(4).trim() // equals "2 5 22 8"
You can then split the line by one or more whitespace characters. The Java regex to do this is "\\s+", since \\s matches a whitespace character, and + means "one or more".
line.substring(4).trim().split("\\s+") // equals ["2", "5", "22", "8"]

If you want to use substring, here is some, probably, non optimal solution. You start from the beginning of the string, look for first number, than continue to find next char that is not number. Do substring between, and then continue looking for next number.
while (i<s.length()){
char c=s.charAt(i);
if(c>='0'&&c<='9'){
j=i;
char c1=s.charAt(j);
while ((c1>='0'&&c1<='9')&&j<s.length()){
c1=s.charAt(j);
j++;
}
strings[p++]=s.substring(i, j);
i=j;
}else i++;
}

I can't tell if these are seperated by a space or not, but if so you can use the .split() method on your String.
Example:
String sampleString = "2 5 22 8";
String[] stringArray = sampleString.split(" ");

Related

Java replace strings between two commas

String = "9,3,5,*****,1,2,3"
I'd like to simply access "5", which is between two commas, and right before "*****"; then only replace this "5" to other value.
How could I do this in Java?
You can try using the following regex replacement:
String input = "9,3,5,*****,1,2,3";
input = input.replaceAll("[^,]*,\\*{5}", "X,*****");
Here is an explanation of the regex:
[^,]*, match any number of non-comma characters, followed by one comma
\\*{5} followed by five asterisks
This means to match whatever CSV term plus a comma comes before the five asterisks in your string. We then replace this with what you want, along with the five stars in the original pattern.
Demo here:
Rextester
I'd use a regular expression with a lookahead, to find a string of digits that precedes ",*****", and replace it with the new value. The regular expression you're looking for would be \d+(?=,\*{5}) - that is, one or more digits, with a lookahead consisting of a comma and five asterisks. So you'd write
newString = oldString.replaceAll("\\d+(?=,\\*{5})", "replacement");
Here is an explanation of the regex pattern used in the replacement:
\\d+ match any numbers of digits, but only when
(?=,\\*{5}) we can lookahead and assert that what follows immediately
is a single comma followed by five asterisks
It is important to note that the lookahead (?=,\\*{5}) asserts but does not consume. Hence, we can ignore it with regards to the replacement.
I considered newstr be "6"
String str = "9,3,5,*****,1,2,3";
char newstr = '6';
str = str.replace(str.charAt(str.indexOf(",*") - 1), newstr);
Also if you are not sure about str length check for IndexOutOfBoundException
and handle it
You could split on , and then join with a , (after replacing 5 with the desired value - say X). Like,
String[] arr = "9,3,5,*****,1,2,3".split(",");
arr[2] = "X";
System.out.println(String.join(",", arr));
Which outputs
9,3,X,*****,1,2,3
you can use spit() for replacing a string
String str = "9,3,5,*****,1,2,3";
String[] myStrings = str.split(",");
String str1 = myStrings[2];

Java split(), use whole word containing a specific character as separator

String string = "3 5 3 -4 2 3 ";
I want to use split() here but I need to a separator to be -4. I don't know which numbers are negative and I need to use split to group positive numbers in separate arrays.
Is it possible?
Edit:
I want to use:
String[] parts = string.split(????);
and receive
parts[0] = "3 5 3"
parts[1] = "2 3"
From what I mentioned in comments, you can use -\\d+ for splitting.
It finds all the places where there is - followed by any number of digits. We can trim the array elements later if we want
Java Code
String Str = new String("3 5 3 -4 2 3");
String[] x = Str.split("-\\d+");
for (String retval: x){
System.out.println(retval.trim());
}
Ideone Demo
You can use the replace method to search for a given string (in this case, -4) and replace it with a delimiter of your choice, perhaps a pipe-bar line (|). Then you can use the split method and use the delimiter that's now inserted to split your array.
string = string.replace(replaceString, "|");
string[] parts = string.split('|');
Admittedly this is a little roundabout, but it's quick, easy, and will work.
Using StringUtils you can do something like this
public static void main(String[] args) {
String splitMe="123-457";
String [] newArray=StringUtils.split(splitMe, "-4");
for (String val:newArray){
System.out.println(val.toString());
}
}
output will be 123 for 1st index and 57 for second index

String.replace() not replacing all occurrences

I have a very long string which looks similar to this.
355,356,357,358,359,360,361,382,363,364,365,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,368,369,313,370,371,372,373,374,375,376,377,378,379,380,381,382,382,382,382,382,382,383,384,385,380,381,382,382,382,382,382,386,387,388,389,380,381,382,382,382,382,382,382,390,391,380,381,382,382,382,382,382,392,393,394,395,396,397,398,399,....
When I tried using the following code to remove the number 382 from the string.
String str = "355,356,357,358,359,360,361,382,363,364,365,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,368,369,313,370,371,372,373,374,375,376,377,378,379,380,381,382,382,382,382,382,382,383,384,385,380,381,382,382,382,382,382,386,387,388,389,380,381,382,382,382,382,382,382,390,391,380,381,382,382,382,382,382,392,393,394,395,396,397,398,399,...."
str = str.replace(",382,", ",");
But it seems that not all occurrences are being replaced. The string which originally had above 3000 occurrences still was left with about 630 occurrences after replacing.
Is the capability of String.replace() limited? If so, is there a possible way of achieving what I need?
You need to replace the trailing comma as well (if one exists, which it won't if last in the list):
str = str.replaceAll("\\b382,?", "");
Note \b word boundary to prevent matching "-,1382,-".
The above will convert:
382,111,382,1382,222,382
to:
111,1382,222
I think the issue is your first argument to replace(), in particular the comma (,) before and after 382. If you have "382,382,383", you will only match the inner ",382," and leave the initial one behind. Try:
str.replace("382,", "");
Although this will fail to match "382" at the very end as it does not have a comma after it.
A full solution might entail two method calls thus:
str = str.replace("382", ""); // Remove all instances of 382
str.replaceAll(",,+", ","); // Compress all duplicates, triplicates, etc. of commas
This combines the two approaches:
str.replaceAll("382,?", ""); // Remove 382 and an optional comma after it.
Note: both of the last two approaches leave a trailing comma if 382 is at the end.
try this
str = str.replaceAll(",382,", ",");
Firstly, remove the preceding comma in your matching string. Then, remove duplicated commas by replacing commas with a single comma using java regular expression.
String input = "355,356,357,358,359,360,361,382,363,364,365,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,360,361,363,366,368,369,313,370,371,372,373,374,375,376,377,378,379,380,381,382,382,382,382,382,382,383,384,385,380,381,382,382,382,382,382,386,387,388,389,380,381,382,382,382,382,382,382,390,391,380,381,382,382,382,382,382,392,393,394,395,396,397,398,399";
String result = input.replace("382,", ","); // remove the preceding comma
String result2 = result.replaceAll("[,]+", ","); // replace duplicate commas
System.out.println(result2);
As dave already said, the problem is that your pattern overlaps. In the string "...,382,382,..." there are two occurrences of ",382,":
"...,382,382,..."
----- first occurrence
----- second occurrence
These two occurrences overlap at the comma, and thus Java can only replace one of them. When finding occurrences, it does not see yet what you replace the pattern with, and thus it doesn't see that new occurrence of ",382," is generated when replacing the first occurrence is replaced by the comma.
If your data is known not to contain numbers with more than 3 digits, then you might do:
str.replace("382,", "");
and then handle occurrences at the end as a special case. But if your data can contain big numbers, then "...,1382,..." will be replaced by "...,1,..." which probably is not what you want.
Here are two solutions that do not have the above problem:
First, simply repeat the replacement until no changes occur anymore:
String oldString = str;
str = str.replace(",382,", ",");
while (!str.equals(oldString)) {
oldString = str;
str = str.replace(",382,", ",");
}
After that, you will have to handle possible occurrences at the end of the string.
Second, if you have Java 8, you can do a little more work yourself and use Java streams:
str = Arrays.stream(str.split(","))
.filter(s -> !s.equals("382"))
.collect(Collectors.joining(","));
This first splits the string at ",", then filters out all strings which are equal to "382", and then concatenates the remaining strings again with "," in between.
(Both code snippets are untested.)
Traditional way:
String str = ",abc,null,null,0,0,7,8,9,10,11,12,13,14";
String newStr = "", word = "";
for (int i=0; i<str.length(); i++) {
if (str.charAt(i) == ',') {
if (word.equals("null") || word.equals("0"))
word = "";
newStr += word+",";
word = "";
} else {
word += str.charAt(i);
if (i == str.length()-1)
newStr += word;
}
}
System.out.println(newStr);
Output:
,abc,,,,,7,8,9,10,11,12,13,14

Split a String at every 3rd comma in Java

I have a string that looks like this:
0,0,1,2,4,5,3,4,6
What I want returned is a String[] that was split after every 3rd comma, so the result would look like this:
[ "0,0,1", "2,4,5", "3,4,6" ]
I have found similar functions but they don't split at n-th amount of commas.
NOTE: while solution using split may work (last test on Java 17) it is based on bug since look-ahead in Java should have obvious maximum length. This limitation should theoretically prevent us from using + but somehow \G at start lets us use + here. In the future this bug may be fixed which means that split will stop working.
Safer approach would be using Matcher#find like
String data = "0,0,1,2,4,5,3,4,6";
Pattern p = Pattern.compile("\\d+,\\d+,\\d+");//no look-ahead needed
Matcher m = p.matcher(data);
List<String> parts = new ArrayList<>();
while(m.find()){
parts.add(m.group());
}
String[] result = parts.toArray(new String[0]);
You can try to use split method with (?<=\\G\\d+,\\d+,\\d+), regex
Demo
String data = "0,0,1,2,4,5,3,4,6";
String[] array = data.split("(?<=\\G\\d+,\\d+,\\d+),"); //Magic :)
// to reveal magic see explanation below answer
for(String s : array){
System.out.println(s);
}
output:
0,0,1
2,4,5
3,4,6
Explanation
\\d means one digit, same as [0-9], like 0 or 3
\\d+ means one or more digits like 1 or 23
\\d+, means one or more digits with comma after it, like 1, or 234,
\\d+,\\d+,\\d+ will accept three numbers with commas between them like 12,3,456
\\G means last match, or if there is none (in case of first usage) start of the string
(?<=...), is positive look-behind which will match comma , that has also some string described in (?<=...) before it
(?<=\\G\\d+,\\d+,\\d+), so will try to find comma that has three numbers before it, and these numbers have aether start of the string before it (like ^0,0,1 in your example) or previously matched comma, like 2,4,5 and 3,4,6.
Also in case you want to use other characters then digits you can also use other set of characters like
\\w which will match alphabetic characters, digits and _
\\S everything that is not white space
[^,] everything that is not comma
... and so on. More info in Pattern documentation
By the way, this form will work with split on every 3rd, 5th, 7th, (and other odd numbers) comma, like split("(?<=\\G\\w+,\\w+,\\w+,\\w+,\\w+),") will split on every 5th comma.
To split on every 2nd, 4th, 6th, 8th (and rest of even numbers) comma you will need to replace + with {1,maxLengthOfNumber} like split("(?<=\\G\\w{1,3},\\w{1,3},\\w{1,3},\\w{1,3}),") to split on every 4th comma when numbers can have max 3 digits (0, 00, 12, 000, 123, 412, 999).
To split on every 2nd comma you can also use this regex split("(?<!\\G\\d+),") based on my previous answer
Obligatory Guava answer:
String input = "0,0,1,2,4,5,3,4,6";
String delimiter = ",";
int partitionSize = 3;
for (Iterable<String> iterable : Iterables.partition(Splitter.on(delimiter).split(s), partitionSize)) {
System.out.println(Joiner.on(delimiter).join(iterable));
}
Outputs:
0,0,1
2,4,5
3,4,6
Try something like the below:
public String[] mySplitIntoThree(String str)
{
String[] parts = str.split(",");
List<String> strList = new ArrayList<String>();
for(int x = 0; x < parts.length - 2; x = x+3)
{
String tmpStr = parts[x] + "," + parts[x+1] + "," + parts[x+2];
strList.add(tmpStr);
}
return strList.toArray(new String[strList.size()]);
}
(You may need to import java.util.ArrayList and java.util.List)
Nice one for the coding dojo! Here's my good old-fashioned C-style answer:
If we call the bits between commas 'parts', and the results that get split off 'substrings' then:
n is the amount of parts found so far,
i is the start of the next part,
startIndex the start of the current substring
Iterate over the parts, every third part: chop off a substring.
Add the leftover part at the end to the result when you run out of commas.
List<String> result = new ArrayList<String>();
int startIndex = 0;
int n = 0;
for (int i = x.indexOf(',') + 1; i > 0; i = x.indexOf(',', i) + 1, n++) {
if (n % 3 == 2) {
result.add(x.substring(startIndex, i - 1));
startIndex = i;
}
}
result.add(x.substring(startIndex));

Splitting and assigning a string with whitespace as the delimeter

I need help splitting this string, but i can't seem to come with the right way of doing it.
Suppose I have two numbers on a line
12 101
I would like to take the first and assign it to variable, and then take the second and assign it to a variable, this may sounds easy, but for me i can't come up with the right way to do it?
Split the string on space which will give you an array of strings that can be stored in two variables. If necessary, you can convert them to ints as shown below:
String text = "12 101";
String[] split= text.split("\\s+");
String first = split[0];
String second = split[1];
//if you want them as ints
int firstNum = Integer.parseInt(first);
int secondNum = Integer.parseInt(second);
String[] result = myString.split(" ");
should work. Then you can assign the values to a variable from the array if you want. Though you should note that if there are two spaces, it will create an array with length of three, the middle element being an empty string.
String s = "12 101";
String[] splitted = s.split("\s"); // \s = any whitespace character except newline
String[] myStringArray = myString.split(" ");
will split the string into an array myStringArray
String text = "12 101";
String[] splitted = text.split("\\s+");
System.out.println(splitted[0]);
System.out.println(splitted[1]);
Will print:
12
101
Using \s+ splits the string at every whitespace in your text. Multiple whitespaces are ignores.
Only doing split(" "); will result in empty fields (e.g. "102 12 4" => [102, , 12, 4]).

Categories