Detect an array from text file - java

I have some files containing text, from which I have to extract some information, among which I have a 2-dimensional double array(sometimes it might be missing - therefore you'll find the "if" clause).
This is the way the file is formatted:
Name=fileName
groups={ group1=groupName group2=groupName minAge= maxAge= ages=[[18.0,21.0,14.7],[17.3,13.0,12.0]] }
I am using java.nio.file.Files, java.nio.file.Path and java.io.Bufferedreader to read these files, but I am having problems while trying to convert the Strings representing the arrays to real java Arrays:
Path p = Paths.get(filename);
try(BufferedReader br = Files.newBufferedReader(p)) {
String line = br.readLine();
String fileName = line.split("=")[1];
line = br.readLine();
String[] arr = line.split("=");
String group1 = arr[2].split(" ")[0];
String group2 = arr[3].split(" ")[0];
Integer minAge = Integer.parseInt(arr[4].split(" ")[0]);
Integer maxAge = Integer.parseInt(arr[5].split(" ")[0]);
double[][] ag = null;
if (line.contains("ages")) {
String age = arr[6].trim().replace("}", "").replace("[[", "").replace("]]", "").trim();
String[] arrAge = weights.split(",");
//don't know what to do here from now on, since the number of arrays inside
//the first one may vary from 1 to 2 (e.g I might find: [[3.0, 4.0]] or [[3.0, 7.0],[4.0,5.0]])
//this is what I was trying to do
ag = new double[1][arrAge.length];
for (int i = 0; i < arrAge.length; i++)
ag[0][i] = Double.parseDouble(arrAge[i]);
}
}
catch (Exception e) {
e.printStackTrace();
}
Is there any way to detect the array from the text without doing what I am trying to do in my code or is there any way to extract a correct 2-dimensional array by reading a file formatted that way?
One more question: is there a way to print a 2-dimensional array like that? If yes, how? (by using Arrays.toString I only get something like this: [[D#69222c14])

You can use regex to extract the two dimensional array from any string.
String groups="{ group1=groupName group2=groupName minAge= maxAge= ages=[[18.0,21.0,14.7],[17.3,13.0,12.0]] }";
String pattern = "(\\[\\[.+\\]\\])";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(groups);
if (m.find( ))
System.out.println(m.group());
The Output for the above code is:
[[18.0,21.0,14.7],[17.3,13.0,12.0]]

Related

How to extract objects separated by semi-colon in another file in Java

As part of a project I'm working on, I want to parse/extract objects separated by semi-colons in a separate file on each line, so that I can create new objects corresponding to the ones on each line in the file whilst reading it.
I will have a file which will be taken as a parameter into a method - the file will will contain Character objects which are separated by semi-colons as demonstrated below in an example. The numbers represent level and ExperiencePoints respectively.
Mario(1,2);Luigi(2,3);Bowser(1,4);Toad(1,4);Yoshi(0,2)
Mario(2,2);Luigi(3,3);Bowser(1,4);Toad(1,4);Yoshi(0,2)
Mario(3,2);Luigi(4,3);Bowser(2,4);Toad(1,4);Yoshi(2,2)
Mario(4,2);Luigi(5,3);Bowser(2,4);Toad(2,4);Yoshi(2,2)
Mario(5,2);Luigi(6,3);Bowser(2,4);Toad(2,4);Yoshi(3,2)
Mario(6,2);Luigi(7,3);Bowser(3,4);Toad(2,4);Yoshi(3,2)
So far, I've written a method which looks like this; it takes a file as a parameter and reads it line by line. I cannot work out how to parse a file with values separated by semi-colons however; do I have to create a separate method to do this? Would appreciate if someone can point me in the right direction.
public void main(String fileName)
throws IOException {
try {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
} catch (FileNotFoundException e) {
System.out.println("Error accessing file");
e.printStackTrace();
}
}
I apologize if the scope requires buffered reader, but inside your try method you could do:
String myFileAsText = new String(Files.readAllBytes(Paths.get(fileName)));
List<String> myObjects = Arrays.asList(myFileAsText.split("[;\r\n]"));
Which will give you an array of each element in String form, which you'll have to parse into your objects by iterating through.
Lets ignore the file part and just consider a String line that you want to parse.
String line = "Mario(1,2);Luigi(2,3);Bowser(1,4);Toad(1,4);Yoshi(0,2)"
Now, you want to parse your line.
String[] tokens = line.split(";");
The resulting array will have:
{ "Mario(1,2)", "Luigi(2,3)", ...}
Now you want to parse the i'th token.
String token = tokens[i]
if(token.contains("Mario")){
//parse out the ints possibly with a scanner and create a Mario
}
Another way to parse your line is to use a regex.
Pattern p = Pattern.compile("(\\w+)\\((\\d+),(\\d+)\\)");
Matcher m = p.matcher(line);
List<Character> characters = new ArrayList<>();
while(m.find()){
String name = m.group(1);
int exp = Integer.parseInt( m.group(2) );
int level = Integer.parseInt( m.group(3) );
Character c = new Character( name , exp, level );
characters.add( c );
}
If you need a different constructor based on the name you could do a switch statement.
Character c;
switch(name){
case "Mario":
c = new Mario(name, exp, level);
break;
case "Luigi":
c = new Mario(name, exp, level);
break;
default:
c = new Character(name, exp, level);
}
characters.add(c);
Another solution would be to serialize your objects using JSON.

Replace quotes in String

I have to replace all the commas that are between double quotes with a dot.
I'm trying to do that with the replace and replaceAll Java's methods. But I still didn't sort out a solution.
Can someone help me?
EDIT:
I have to manually parse a csv file to object. So I'm trying to string split each input line, but one number has a comma inside so i'm getting more datas than I need for the split.
Example: I have to split this string.
"""LASER MEDIA SOCIETA' COOPERATIVA""",CNF146010,FM (S),PIAZZA UMBERTO I - PISTICCI,MT,40N2323,16E3328,383,,"99,1",CITY RADIO,"H: --V: 32 dBW",0.0
Notice that I have "99,1" and the ,, before that are putting me in trouble.
Scanner var = new Scanner(new BufferedReader(new FileReader ("t1.csv")));
ArrayList<Catasto> obj = new ArrayList();
String data = var.nextLine();
String data2 = null;
String full = null;
int j = 0;
while (var.hasNextLine()) {
data = var.nextLine();
data2 = var.nextLine();
full = data + data2;
//full = full.replaceAll("\"*[,]*\"", "."); attempt 1
System.out.println(full);
ArrayList<String> parts = new ArrayList();
String[] parti = full.split(",");
//for (int i = 0; i<parti.length; i++) { this is because I'm trying to change empty string with a null
//if (parti[i] == " ") in order to solve this error: java.lang.NumberFormatException: For input string: ""
// parti[i] = null;
//}
for (int i = 0; i<12; i++) {
parts.add(parti[i]);
}
Catasto foo = new Catasto(parts);
obj.add(foo);
}
var.close();
EDIT 2:
I have solved the problem of the comma between the double quotes. But I don't know why the error: java.lang.NumberFormatException: For input string: ""
You're going to struggle to do it with a single replaceAll or replace as you need to determine pairs of quotes. Your best bet is to match pairs of quotes and the use replaceAll for the group to change the comma to a full stop.
String input = "\"One,Two,There\",\"Four,Five,Six\"";
Matcher m = Pattern.compile("\"[^\"]*\"").matcher(input);
StringBuffer sb = new StringBuffer();
while(m.find()) {
m.appendReplacement(sb, m.group().replaceAll(",", "."));
}
m.appendTail(sb);
String output = sb.toString(); // "One.Two.There","Four.Five.Six"

How CSV parsing can be utilized - JAVA

I am given a file that will read the following:
"String",int,int
"String",int,int
"String",int,int
...
Given an unknown number of variables, a while (scanner.hasNextLine()) can solve to the number of entries. My goal is to take these three pieces of data and store them into a Node. I am using the method BinaryTree.addNode(String, int, int) for this. My issue comes to when I am trying to read in the data. I am trying to remove the commas within the document and then attempting to re-read the data using the following:
Scanner firstpass = new Scanner(file);
String input = firstpass.nextLine().replaceAll(",", "");
Scanner secondpass = new Scanner(input);
String variable1 = secondpass.next();
int variable2 = secondpass.nextInt();
int variable3 = secondpass.nextInt();
This however is a very innefective way of going about this.
UPDATED
The compiling errors can be fixed with the following:
try {
Scanner scanner1 = new Scanner(file);
while (scanner1.hasNextLine()) {
String inventory = scanner1.nextLine().replaceAll(",", " ");
Scanner scanner2 = new Scanner(inventory);
while (scanner2.hasNext()){
String i = scanner2.next();
System.out.print(i);
}
scanner2.close();
}
scanner1.close();
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
which gives me the output:
"String"intint"String"intint"String"intint...
So I know I am on the right track. However any (spaces) within the "String" variable are removed. So they would output "SomeString" instead of "Some String". Also I still don't know how to remove the "" from the strings.
The format you've shown matches the CSV (Comma-Separated Values) format, so your best option is to use a CSV parser, e.g. Apache Commons CSV ™.
If you don't want to add a third-party library, you could use Regular Expression to parse the line.
Reading lines from a file should not be done with a Scanner. Use a BufferedReader instead. See Scanner vs. BufferedReader.
try (BufferedReader in = new BufferedReader(new FileReader(file))) {
Pattern p = Pattern.compile("\"(.*?)\",(-?\\d+),(-?\\d+)");
for (String line; (line = in.readLine()) != null; ) {
Matcher m = p.matcher(line);
if (! m.matches())
throw new IOException("Invalid line: " + line);
String value1 = m.group(1);
int value2 = Integer.parseInt(m.group(2));
int value3 = Integer.parseInt(m.group(3));
// use values here
}
} catch (IOException | NumberFormatException ex) {
ex.printStackTrace();
}
Note that this will not work if the string contains escaped characters, e.g. if it contains embedded double-quotes. For that, you should use a parser library.
The code above will correctly handle embedded spaces and commas.
I would instead of using
String input = firstpass.nextLine().replaceAll(",", "");
Scanner secondpass = new Scanner(input);
String variable1 = secondpass.next();
int variable2 = secondpass.nextInt();
int variable3 = secondpass.nextInt();
Use the following approach
String line = firstpass.nextLine();
String[] temp = line.split(",");
String variable1 = temp[0];
int variable2 = Integer.parseInt(temp[1]);
int variable3 = Integer.parseInt(temp[2]);

Identifying valid input of character in a string, or array Java

We were asked to check following inputs from a string in every line example
A = B + C
A = 3 + C + 99
B = ( ( 4 + B ) + D )
Now the consideration that these strings would be wrong are
+ - :: if two operator are next together
A B :: IF two letters are next together
1 2 :: if two numbers are next together
all numbers must be integer
Letters must only be A B or C
the parenthesis should have endings... ( ) not like ( (
Now what I think one of the solutions are the if else and using isdigit, isalpha and checking the character that are right next to each other if they are the same character type isdigit,isspacechar,isalpha example if this is the (currently checking [1][3]) array[1][5] = ['A','=','B','+','C'] it would look like as if ['A','=','B'/*checking*/,'+','C'/*checking*/]
since the input is from a text file i'm doing this
fR = new FileReader("input.txt");
bR = new BufferedReader(fR);
Inp = new Scanner(fR);
x=0;
while(Inp.hasNextLine()) {
int y=0;
while(Inp.hasNextLine()) {
stringarray[x][y];
y++;
}
x++;
}
How am I suppose to do it?
Or should I just stick with array char but again I don't know how to skip the spaces.. so that would go to a different discussion I guess.. I have no idea how to do the parenthesis part.
Talking about skipping spaces use the trim() method using a dot connector to remove the whitespaces of both side of the string.
It looks like these are two separate questions.
1) How to read the file contents and create something to loop over in your program
2) How to perform checking
For (1) I would suggest something like
List<String> lines = new ArrayList<String>();
fR = new FileReader("input.txt");
bR = new BufferedReader(fR);
inp = new Scanner(fR);
try {
while(inp.hasNextLine()){
lines.add(imp.nextLine());
}
imp.close();
} catch (FileNotFoundException | IOException e) {
e.printStackTrace();
}
and for (2)
String regex = "<regex for checking goes here>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher("");
for (String l : lines) {
if (matcher.reset(s).matches()) {
// do something
}
}
You can test regex strings online here: https://regex101.com/
It may take a while to get the string right

Retrieving part of a string using a delimiter

Okay So I am creating an application but I'm not sure how to get certain parts of the string. I have read In a file as such:
*tp*|21394398437984|163600
*2*|AAA|1234567894561236|STOP|20140527|Success||Automated|DSPRN1234567
*2*|AAA|1234567894561237|STOP|20140527|Success||Automated|DPSRN1234568
*3*|2
I need to read the lines beginning with 2 so I done:
s = new Scanner(new BufferedReader(new FileReader("example.dat")));
while (s.hasNext()) {
String str1 = s.nextLine ();
if(str1.startsWith("*2*")) {
System.out.print(str1);
}
}
So this will read the whole line I'm fine with that, Now my issue is I need to extract the 2nd line beginning with numbers the 4th with numbers the 5th with success and the 7th(DPSRN).
I was thinking about using a String delimiter with | as the delimiter but I'm not sure where to go after this any help would be great.
You should use String.split("|"), it will give you an array - String[]
Try following:
String test="*2*|AAA|1234567894561236|STOP|20140527|Success||Automated|DSPRN1234567";
String tok[]=test.split("\\|");
for(String s:tok){
System.out.println(s);
}
Output :
*2*
AAA
1234567894561236
STOP
20140527
Success
Automated
DSPRN1234567
What you require will be placed at tok[2], tok[4], tok[5] and tok[8].
Just split the returned line based on your search, which would return an array of String elements where you can retrieve your elements based on their index:
s = new Scanner(new BufferedReader(new FileReader("example.dat")));
String searchLine = "";
while (s.hasNext()) {
searchLine = s.nextLine();
if(searchLine.startsWith("*2*")) {
break;
}
}
String[] strs = searchLine.split("|");
String secondArgument = strs[2];
String forthArgument = strs[4];
String fifthArgument = strs[5];
String seventhArgument = strs[7];
System.out.println(secondArgument);
System.out.println(forthArgument);
System.out.println(fifthArgument);
System.out.println(seventhArgument);

Categories