Load CSV and split attributes - java

I'm trying to load a csv file and split 'timespan' into 'begin' and 'end'. If the timespan consists of one date 'begin' and 'end' are the same.
timespan,someOtherField, ...
27.03.2017 - 31.03.2017,someOtherValue, ...
31.03.2017,someOtherValue, ...
Result:
begin,end,someOtherField
27.03.2017,31.03.2017,someOtherValue, ...
31.03.2017,31.03.2017,someOtherValue, ...
At the moment I'm loading the file line by line using OpenCSV. This works pretty good but i don't know how to split one attribute. Propably I have to parse the CSV into an array?

For any line l you can use StringTokenizer to get the tokens separated by ,:
StringTokenizer tokens = new StringTokenizer(l, ",")
The first token represents timespan, so:
String timespan = tokens.nextToken()
Then you can split timespan based on " - ", so:
String[] startEnd = timespan.split(" - ");
Finally, you have to compute the size of the startEnd, if startEnd.length == 1, then you absolutely know that start begin and end coincides, so startEnd[0],startEnd[0]
otherwise the result would look like the following startEnd[0],startEnd[1]
I hope this could help you solve the problem.

Thanks for your answer! I parsed the csv into an extra class and created an object for each record. The code below shows the splitting of the timespan. I will now rebuild a new csv file from all objects.
// Load CSV as Booking objects
ArrayList<Booking> bookings = Utils.readCSV(csvClean);
for (int i = 0; i < bookings.size(); i++) {
String timespan = bookings.get(i).getTimespan();
String begin = "";
String end = "";
if (timespan.contains(" - ")) {
// Split timespan and set values
String[] parts = timespan.split(" - ");
begin = parts[0].trim();
end = parts[1].trim();
bookings.get(i).setBegin(begin);
bookings.get(i).setEnd(end);
} else {
bookings.get(i).setBegin(timespan.trim());
bookings.get(i).setEnd(timespan.trim());
} // end if else
} // end for

Related

Trying to read the contents of a file into an array, but the contents are separated by a colon

Inside my file is the two-letter abbreviation of each state followed by the full name of the state, and each state abbreviation and name is separated by a colon.
Like this:
al:Alabama
ak:Alaska
I need to read this into an array of 52x2 and I am not sure how to do that. The code I have now just reads each line from the file into the array without separating the abbreviation and name.
String[][] states = new String[52][2];
while (input2.hasNext()) {
for (int row = 0; row < states.length; row++) {
for (int column = 0; column < states[row].length; column++) {
states[row][column] = input2.next();
System.out.printf("%s%n", states[row][column]);
}
}
}
You can try below code(Comments inline):
String[][] states = new String[52][2];
int row = 0;
while (input2.hasNext()) {
// Read whole line from the file
String line = input2.nextLine();
// Split string into tokens with : character.
// It means, Line: al:Alabama is converted to
// ["al", "Alabama"] in tokens
String tokens[] = line.split(":");
// Store first token in first column and similarly for second.
states[row][0] = tokens[0];
states[row][1] = tokens[1];
row++;
}
Use the predefined split() String function:
// A string variable.
String myString = "Hello:World";
// split the string by the colon.
String[] myStringArray = myString.split(":");
// print the first element of the array.
System.out.println(myStringArray[0]);
// print the second element of the array.
System.out.println(myStringArray[1]);
As your data also adheres to the .properties format, you can use the Properties class.
Path file = Paths.get("...");
Properties properties = new Properties(52); // Initial capacity.
properties.load(Files.newBufferedReader(path, StandardCharsets.ISO_8859_1));
properties.list(System.out);
String name = properties.get("AR", "Arabia?");
Here I used an overloaded get where one can provide a default ("Arabia?") in case of failure.
This one line version makes use of NIO Files to load from file and converts the contents in a stream:
String[][] states = Files.readAllLines(Path.of("states.cfg")).stream().map(s -> s.split(":", 2)).toArray(String[][]::new);

How to merge many List<String> elements in one based on double quote delimiter in java

I have a CSV file generated in other platform (Salesforce), by default it seems Salesforce is not handling break lines in the file generation in some large text fields, so in my CSV file I have some rows with break lines like this that I need to fix:
"column1","column2","my column with text
here the text continues
more text in the same field
here we finish this","column3","column4"
Same idea using this piece of code:
List<String> listWords = new ArrayList<String>();
listWords.add("\"Hi all");
listWords.add("This is a test");
listWords.add("of how to remove");
listWords.add("");
listWords.add("breaklines and merge all in one\"");
listWords.add("\"This is a new Line with the whole text in one row\"");
in this case I would like to merge the elements. My first approach was to check for the lines were the last char is not a ("), concatenates the next line and just like that until we see the las char contains another double quote.
this is a non working sample of what I was trying to achieve but I hope it gives you an idea
String[] csvLines = csvContent.split("\n");
Integer iterator = 0;
String mergedRows = "";
for(String row:csvLines){
newCsvfile.add(row);
if(row != null){
if(!row.isEmpty()){
String lastChar = String.valueOf(row.charAt(row.length()-1));
if(!lastChar.contains("\"")){
//row += row+" "+csvLines[iterator+1].replaceAll("\r", "").replaceAll("\n", "").replaceAll("","").replaceAll("\r\n?|\n", "");
mergedRows += row+" "+csvLines[iterator+1].replaceAll("\r", "").replaceAll("\n", "").replaceAll("","").replaceAll("\r\n?|\n", "");
row = mergedRows;
csvLines[iterator+1] = null;
}
}
newCsvfile.add(row);
}
iterator++;
}
My final result should look like (based on the list sample):
"Hi all This is a test of how to remove break lines and merge all in one"
"This is a new Line with the whole text in one row".
What is the best approach to achieve this?
In case you don't want to use a CSV reading library like #RealSkeptic suggested...
Going from your listWords to your expected solution is fairly simple:
List<String> listSentences = new ArrayList<>();
String tmp = "";
for (String s : listWords) {
tmp = tmp.concat(" " + s);
if (s.endsWith("\"")){
listSentences.add(tmp);
tmp = "";
}
}

Split complex string within a muliple sub string with same special character

I am trying to parse the string with semicolon with multiple substrings, here are the example
String temp = "SIM1_TM_4G3G2G_DE;ANY_RAT;TCNAME_Flight_Mode_Toggle;TIME_60;120;90;30"
Expected output required would be to display only values after the TIME_:
60
120
90
30
I have tried with the following code it did not do the following need
String[] args_val=temp.split(";");
log("STARTING THE LOOP");
for(int ix=0; ix<args_val.length;ix++)
{
log("args_val["+ix+"]-" +args_val[ix]);
//TIME is considered in seconds
if(args_val[ix].contains(TIME"))
{
log("args_val[ix] length -" +args_val[ix].length());
String sTime = args_val[ix].substring(args_val[ix].indexOf("TIME_") +5, args_val[ix].length());
log("print sTime-" +sTime);
}
}
Try this:
String output = temp.substring(temp.indexOf("TIME_") + 5)
.replaceAll(";", "");
You may remove all the substring from start till and including ;TIME_ with the .*;TIME_ regex (note that the .* is a greedy dot matching pattern and will match from the start of the string till the last ;TIME_ on the line), and then split the rest with ;:
String temp = "SIM1_TM_4G3G2G_DE;ANY_RAT;TCNAME_Flight_Mode_Toggle;TIME_60;120;90;30";
String[] res = temp.replaceFirst(".*;TIME_", "").split(";");
System.out.println(res[0]);
System.out.println(res[1]);
System.out.println(res[2]);
System.out.println(res[3]);
See the Java demo
This will work if the string you mention is always in this format.

Join a json String values with new line

I need to return json array each element in new line. but instead it's printing in one line. I tried using '/n' and space but it's not working.
String json = null;
//split cookie with delimiter to store in array
String wl[] = wishList.split("~");
//JSON RETURN VALUE
json = "[\"";
for(int i = 0; i < wl.length; ++i) {
json += wl[i];
//tried but didn't work
//json.split("\n");
}
json += "\"]";
System.out.println(json);
so i tried cancatinating in for loop but it didn't work.
I need out like this
1.abc
2.bcd
3.efg
but i'm getting this output
1.abcbcdefg
What you are trying to do (if I get it right) is to split a String on the ~ and creating a JSON array with it (one separate line).
Did you thought about simply replacing the character ?
String json = "[" + wishlist.replace("~", ",\n") + "]"; //Added a , to separated each elements
But if you want to do it yourself,
String json = "[";
for(int i = 0; i < wl.length; ++i) {
json += wl[i] + ",\n";
}
json += "]";
You need to add the newLine character, not split it again.
Off course, as pointed, this should be done using a Library design to do it but here is a simple correction of you code.
PS : I didn't write the needed \" for redability. But this can be easily added in both solutions.
I tried using '/n' and space but it's not working.
You should use "\n" in your JSON String to add new line and not "/n", it is not the same thing. You should do the same thing for the regex pattern.
3. Line Separator is '\n'
This means '\r\n' is also supported because trailing white space is ignored >when parsing JSON values.
The last character in the file may be a line separator, and it will be
treated the same as if there was no line separator present.
Source : http://jsonlines.org/
Edit
A Json array has comma to separate values of the array and string should be between quotes or double quotes. but doesn't need "\" at the begining and at the end.
You could get this String :
["abc",
"bcd",
"efg"]
with this code :
final String STRING_DOUBLE_QUOTE="\"";
String json = null;
// split cookie with delimiter to store in array
String wl[] = wishList.split("~");
// JSON RETURN VALUE
json = "[";
for (int i = 0; i < wl.length; ++i) {
if (!json.equals("[")) {
json += ",\n";
}
json += STRING_DOUBLE_QUOTE + wl[i] + STRING_DOUBLE_QUOTE;
}
json += "]";
System.out.println(json);
If you want it to be on multiple lines, you're gonna have to save it in multiple elements i.e. an array.
Try this:
String wl[] = wishList.split("~");
for(int i = 0; i < wl.length; ++i){
System.out.println(wl[i]);
}
Unsure if this is what you're asking for, but this is the answer to your written question

Inserting Newline character before every number occurring in a string?

I have String of format something like this
String VIA = "1.NEW DELHI 2. Lucknow 3. Agra";
I want to insert a newline character before every digit occurring succeeded a dot so that it final string is like this
String VIA = "1.NEW DELHI " +"\n"+"2. Lucknow " +"\n"+"3. Agra";
How can I do it. I read Stringbuilder and String spilt, but now I am confused.
Something like:
StringBuilder builder = new StringBuilder();
String[] splits = VIA.split("\d+\.+");
for(String split : splits){
builder.append(split).append("\n");
}
String output = builder.toString().trim();
The safest way here to do that would be go in a for loop and check if the char is a isDigit() and then adding a '\n' before adding it to the return String. Please note, I am not sure if you want to put a '\n' before the first digit.
String temp = "";
for(int i=0; i<VIA.length(); i++) {
if(Character.isDigit(VIA.charAt(i)))
temp += "\n" + VIA.charAt(i);
} else {
temp += VIA.charAt(i);
}
}
VIA = temp;
//just use i=1 here of you want to skip the first charachter or better do a boolean check for first digit.

Categories

Resources