I am trying to fetch the string after the third slash. But i don' know how to do it. I have used split but that's not what I want.
for(String obj2: listKey.getCommonPrefixes()){
Map<String, String> map = new HashMap<String, String>();
String[] id = obj2.split("/");
if (id.length > 3) {
String name = id[3];
map.put("id", name);
map.put("date", "null");
map.put("size", String.valueOf(obj2.length()));
keys.add(map);
}
}
id[3] gives me only id[3] but i want everything after the third slash? how can i do that?
You can replace
String[] id = obj2.split("/");
by
String[] id = obj2.split("/", 4);
From the javadoc :
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. 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.
Related
I am trying to split a string into string array. And I have stumbled to something strange to me. I don't understand why it works like this.
String one, two;
one = "";
two = ":";
String[] devided1 = one.trim().split(":");
String[] devided2 = two.trim().split(":");
System.out.println("size: "+ devided1.length);
System.out.println("size: "+ devided2.length);
I get output:
size: 1
size: 0
Why is empty string giving me size of one, but string that only has the delimiter gives my array size of 0?
I saw more confusing things like: that size of "::" is 0, but size of ": :" is 2, not 3.
Can someone please explain it to me?
See the doc comment in source code or documentation for public String[] split(String regex, int limit) method.
Case 1:
String one = "";
String[] devided1 = one.trim().split(":");
The resulting array will have 1 element = original string String[1] [""], because expresion ":" was not match any part of the input string.
According to documentation:
If the
* expression does not match any part of the input then the resulting array
* has just one element, namely this string.
Case 2:
String two = ":";
String[] devided2 = two.trim().split(":");
The split(":") has default limit = 0. It means that from the resulting array trailing empty strings will be removed. So method splits ":" string to array with two empty strings and then remove them and as result we get empty array.
According to documentation:
If limit 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.
Case 3:
String two = ":";
String[] devided2 = two.trim().split(":", -1);
We will get an array with two empty strings.
According to documentation:
If limit is non-positive then the pattern will be applied as many
times as possible and the array can have any length
Case 4:
String two = "::";
String[] devided2 = two.trim().split(":");
We will get empty array. It is the same like Case 2.
Case 5:
String one = ": :";
String[] devided1 = one.trim().split(":");
The method will split string to three array elements ["", " ", ""] and then remove empty strings from the end of array, because limit = 0. We will get String[2] ["", " "].
According to documentation:
If limit 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.
This link is helpful:
https://konigsberg.blogspot.com/2009/11/final-thoughts-java-puzzler-splitting.html
Basically, it is for perl compatibility.
You can use split(":", -1) here if you don't want that behavior.
Otherwise, split(":") defaults to split(":", 0), and the difference is:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#split(java.lang.String,int)
If the limit 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 the limit is negative then the pattern will be applied as many times as possible and the array can have any length.
In case of ":" being splitted, it would result in {"" , ""}, but empty traling spaces will be discarded, so it will return an empty array.
I have a number of large strings looking like this:
"text(24), text_2(5), text_4(822)..."
I'm trying to check if a specific text exists and get the corresponding value.
Is there a quick way to do this?
Edit:
I have an array with all possible text values. At the moment I use foreach to check for text values.
I have the string text_2 and what I need is the corresponding 5 as an integer.
You can use regex to extract all the text element from the String and store them into a map, e.g:
String s = "text(24), text_2(5), text_4(822)";
Pattern pattern = Pattern.compile("([a-zA-Z]*(_)?[0-9]*\\([0-9]+\\))");
Matcher matcher = pattern.matcher(s);
Map<String, Integer> valuesMap = new HashMap<>();
while(matcher.find()){
String[] tokens = matcher.group().split("(?=\\([0-9]+\\),?)");
String key = tokens[0];
Integer value = Integer.parseInt(tokens[1].substring(1, tokens[1].length() - 1));
valuesMap.put(key, value);
}
System.out.println(valuesMap);
Once done, you can call valuesMap.get("test_2"); to get the corresponding value. This is how the above example works:
It splits text into tokens containing <text>(<Value)
It then splits each token again, into text and value and places these into a Map.
Since you need to do this a number of times. I suggest you split the string and build a map from the text to its value, this is O(n). After that, your lookups are only O(1) if you use HashMap.
String text = "text(24), text_2(5), text_4(822)";
Map<String, Integer> map = new HashMap<>();
String[] split = text.split(", ");
for(String s:split){
//search for the position of "(" and ")"
int start = 0;
int end = s.length()-1;
while(s.charAt(start) != '(')
start++;
while(s.charAt(end) != ')')
end--;
//put string and matching value in the map
map.put(s.substring(0, start), Integer.parseInt(s.substring(start+1, end)));
}
System.out.println(map);
I also ran some benchmarks for a string containing 10000 entries. And this approach was about 4 times faster than a regex approach. (38 ms vs 163 ms)
I have a many string wich are really randomly sized like : 5 chars to 12000 randomly.
Eg:
String 1 : A,b,C,d
String 2 :23,343,342,4535,4535,453,234,
String 3 : ,asdsfdfdasgfdsfsf,dsfdsfdsfdsfsdfdf,sdsfdsfdsfsdf, <- and this around another 1000 times.
I want to upload them to my database by their ID. So my problem is that the oracle database varchar can conatians only 4k bytes.
Edit:
So if the string bigger than 4k. I want a String[] where each element maximum 4000k characters lets count 3900. ( And ofc if i go throught the array I get back the same String, and each array element last "word" is a whole word not sliced)
So my idea is simply if the string.lenth <1000 then go.
else split it by ~4000 stocks but only split after coma.
My solution so far ( without coma care)
for (My_type type: types) {
String[] tokens =
Iterables.toArray(
Splitter
.fixedLength(4000)
.split(type.area),
String.class
);
how can I replace this function to get an "good array"?
I don't think split() is an option. I think you need to use a Matcher to consume as much input as possible, then build a list of captured sections:
Matcher matcher = Pattern.compile(".{1,3999}(,|.$)").matcher(input);
List<String> list = new ArrayList<>();
while (matcher.find())
list.add(matcher.group());
If you really want an array (not recommended)
String[] array = list.toArray(new String[list.size()]);
This regex is greedy and will consume up to 4000 chars that ends with a comma or the end of input. A length of 3999 is used to allow 1 more for the comma itself, and the dot before the end marker $ is to consume one more because $ is zero-width.
This will give you such tokens, in a List<> - hoping that's fine.
for (My_type type: types) {
String longString = type.area;
List<String> tokens = new ArrayList<>();
while (longString.length() > 4000) {
int splitIndex = longString.lastIndexOf(",", 3999);
if (splitIndex < 0) {
// no comma found
throw new IllegalStateException("Cannot split string");
}
tokens.add(longString.substring(0, splitIndex));
longString = longString.substring(splitIndex + 1); // leaving out the comma
}
if (tokens.size() == 0) {
tokens.add(longString);
}
}
I am trying to split a string using String split function, here's an example:
String[] list = " Hello ".split("\\s+");
System.out.println("String length: " + list.length);
for (String s : list) {
System.out.println("----");
System.out.println(s);
}
Here's the output:
String length: 2
----
----
Hello
As you can see, the leading whitespace becoming an empty element in the String array, but the trailing whitespace is not.
Does anyone know why?
You need to use the other split method which specifys the limit and specify a limit of -1
String[] list = " Hello ".split("\\s+", -1);
to preserve the trailing whitespace, - the default behavior is to omit the trailing spaces as per the javadoc
Edit (answer for comment):
To trim the leading space, you can strip off the leading space before splitting the String
String str = " Hello ".replaceAll("^\\s+", "");
String[] list = str.split("\\s+", -1);
From split documentation
This method works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
so in reality split(regex) is the same as using
split(regex, 0);
and its documentation says
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. 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.
so if you want to include trailing empty strings will just have to use non-zero value like
split("\\s+",10);
but this will also limit result array to max 10 elements. To get rid of this problem use some negative number like
split("\\s+",-1);
String s = "10.226.18.158:10.226.17.183:ABCD :AAAA"
My requirement is to split the string at up to 3rd : or up to 2nd :. i.e.
Something like String sa[] = s.split(), but with the regex splitting only up to 3rd or 2nd.
s[0] = "10.226.18.158"
s[1] = "10.226.17.183"
s[2] = "ABCD :AAAA"
According to the String#split() javadoc you can add a number to limit the number of splits.
s.split(":", 3);
Edit: as melwil metions This will return an array of up to the number passed in long.
So in your example of splitting up to 2nd : you would need to pass in 3.
s.split(":",3) returns the output
sa[0] = "10.226.18.158"
sa[1] = "10.226.17.183"
sa[2] = "ABCD :AAAA"
Relevent section quoted from the java doc about how the second argument (limit) works.
The limit parameter controls the number of times the pattern is
applied and therefore affects the length of the resulting array. If
the limit n is greater than zero then the pattern will be applied at
most n - 1 times, the array's length will be no greater than n, and
the array's last entry will contain all input beyond the last matched
delimiter. If n is non-positive then the pattern will be applied as
many times as possible and the array can have any length. 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.
You can split your string basing on one non-whitespece character, \S{1}, followed by a colon, ::
String sa[] = s.split("\\S{1}:");