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
Related
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.
I am working on an assignment where I have to create an interval(which I have already completed) and from a text file, read in the girls names that are found within the interval and put them into an array list. I also have to read in all the male names that start with the letter "J", and then calculate how many male births start with the letter "J" and print out that information. Below is the code I have so far:
public static int generateRandomInt(int lowerLimit, int upperLimit) {
int value = lowerLimit + (int)Math.ceil( Math.random() * ((upperLimit - lowerLimit) + 1)); //generates a random number between 1 and 10
return value;
}// end generateRandomInt
public static void main(String[] args) {
// Read from filename: top20namesNM1994.txt
// Generating a interval, the lower random number comes from 50 to 100, and the upper random number comes from 150 to 200.
// Print out this interval
// Read all the girls names, which birth numbers are inside of the interval you construct, into a array or ArrayList.
// Print out the array.
//Print out all the males names, which start with letter "J".
//Determine how many male births start with names starting with the letter "J", and print out the summary information.
final int LOW1 = 50;
final int LOW2 = 100;
final int HIGH1 = 150;
final int HIGH2 = 200;
ArrayList<String>girlNames = new ArrayList<String>();
String line = "";
int interval_low = generateRandomInt(LOW1, LOW2);
int interval_high = generateRandomInt(HIGH1, HIGH2);
System.out.println("The interval is ( " + interval_low + " , " + interval_high + " )" );
try {
FileReader inputFile = new FileReader("C:\\Users\\drago\\eclipse-workspace-Ch6to7FinalExam2\\MorrisJFinalExam2\\src\\top20namesNM1994.txt");
//Scanner scan = new Scanner (inputFile);
BufferedReader br = new BufferedReader(inputFile);
while((line = br.readLine()) != null) {
line.split("\\s+");
if()
girlNames.add();
}
}
catch(IOException e) {
System.out.println("File not Found!");
}
if()
System.out.println(girlNames.toString());
}
I am stuck on how to get the girl names that are within the interval created and also how to read in the boy names. Attached is the text file.
TextFile
Okay...you know how to read in the text file (somewhat) which is good however you can simplify the code a bit:
ArrayList<String> girlNames = new ArrayList<>();
String filePath = "C:\\Users\\drago\\eclipse-workspace-Ch6to7FinalExam2\\"
+ "MorrisJFinalExam2\\src\\top20namesNM1994.txt";
String line = "";
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
while ((line = br.readLine()) != null) {
// .....................
// ..... Your Code .....
// .....................
}
}
catch (IOException ex) {
ex.printStackTrace();
}
Try With Resources is used here so that your BufferedReader is automatically closed. If all your going to do is read the desired text file then the Scanner object you have commented out in your code is also a pretty good alternative for reading text files if properly used.
It's obvious from your incomplete code that each data line within this file is White-Space or Tab delimited simply based on the Regular Expression ("\\s+") used within the String#split() method (the "\\s+" expression will split a string on any number of white-spaces and or tabs that are contained within that string). Do Note however that the code line where you are using the String#split() method is not completed properly.... If you read the linked tutorial you will find that this method is used to fill a String Array which is good because usually, this is what you want to do with file data lines. Doing so of course allows you to retrieve the exact data portion desired from each data file line.
No one here has a clue what is contained within your specific data text file because like so many others the contents within it is obviously so supper-duper classified that not even fictitious data will suffice. Because of this there is in no way a means provide you with an accurate array index value or values to use against your String Array in order to retrieve your desired data from each data file line. This is good however since it is you who needs to figure this out and once you do you will have the task beaten to submission.
I'll admit it, I'm stumped. It's not a double. It's not outside of the range of an integer. It's not NAN. It's not a non-integer in any way shape or form as far as I can tell.
Why would I get that error?
Here's the code that causes it:
String filename = "confA.txt";
//Make a new filereader to read in confA
FileReader fileReader = new FileReader(filename);
//Wrap into a bufferedReader for sanity's sake
BufferedReader bufferedReader = new BufferedReader(fileReader);
//Get the port number that B is listening to
int portNum = Integer.parseInt(bufferedReader.readLine());
It fails on that last line, stating:
java.lang.NumberFormatException: For input string: "5000"
Which is the number I want.
I've also attempted
Integer portNum = Integer.parseInt(bufferedReader.readLine());
But that didn't work either. Neither did valueOf().
Most probably there is some unprintable character somewhere in your file line. Please consider the following example (this was tested in Java 9 jshell)
jshell> String value = "5000\u0007";
value ==> "5000\007"
jshell> Integer.parseInt(value);
| java.lang.NumberFormatException thrown: For input string: "5000"
| at NumberFormatException.forInputString (NumberFormatException.java:65)
| at Integer.parseInt (Integer.java:652)
| at Integer.parseInt (Integer.java:770)
| at (#15:1)
Here the string contains the "bell" character at the end. It makes parse to fail while it is not printed in exception text. I think you have something similar. The simpliest way to verify this is to check
String line = bufferedReader.readLine();
System.out.println("line length: " + line.length());
The value other than 4 will support my idea.
I had the same problem. I was reading in a flat file with the Buffered reader and saving the contents as an ArrayList of type String, but on performing an integer.parse when retrieving a string value from the list, I realised that there was a whole lot of garbage in the string read from the file, as I got a java.lang.NumberFormatException.
This was the method I implemented with the code (called from my main method) to solve the problem:
`
// class level
private static final Pattern numericPattern = Pattern.compile("([0-9]+).([\\\\.]{0,1}[0-9]*)");
// in main method after reading in the file
String b = stripNonNumeric(stringvaluefromfile);
int a = Integer.parseInt(b);
public static String stripNonNumeric(String number) {
//System.out.println(number);
if (number == null || number.isEmpty()) {
return "0";
}
Matcher matcher = numericPattern.matcher(number);
// strip out all non-numerics
StringBuffer sb = new StringBuffer("");
while (matcher.find()) {
sb.append(matcher.group());
}
// make sure there's only one dot
int prevDot = -1;
for (int i = sb.length() - 1; i >= 0; i--) {
if (sb.charAt(i) == '.') {
if (prevDot > 0) {
sb.deleteCharAt(prevDot);
}
prevDot = i;
}
}
if (sb.length() == 0) {
sb.append("0");
}
return sb.toString();
}`
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]]
i have sorted file and i need to do the following pattern match. I read the row and then compare or do patern match with the row just after it , if it matches then insert the string i used to match after a comma in that row and move on to the next row. I am new to Java and overwhelmed with options from Open CSV to BufferedReader. I intend to iterate through the file till it reaches the end. I may always have blanks and have a dated in quotes. The file size would be around 100 MBs.
My file has data like
ABCD
ABCD123
ABCD456, 123
XYZ
XYZ890
XYZ123, 890
and output is expected as
ABCD, ABCD
ABCD123, ABCD
ABCD456, 123, ABCD
XYZ, XYZ
XYZ890, XYZ
XYZ123, 890, XYZ
Not sure about the best method. Can you please help me.
To open a file, you can use File and FileReader classes:
File csvFile = new File("file.csv");
FileReader fileReader = null;
try {
fileReader = new FileReader(csvFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
You can get a line of the file using Scanner:
Scanner reader = new Scanner(fileReader);
while(reader.hasNext()){
String line = reader.nextLine();
parseLine(line);
}
You want to parse this line. For it, you have to study Regex for using Pattern and Matcher classes:
private void parseLine(String line) {
Matcher matcher = Pattern.compile("(ABCD)").matcher(line);
if(matcher.find()){
System.out.println("find: " + matcher.group());
}
}
To find the next pattern of the same row, you can reuse matcher.find(). If some result was found, it will return true and you can get this result with matcher.groud();
Read line by line and use regex to replace it as per your need using String.replaceAll()
^([A-Z]+)([0-9]*)(, [0-9]+)?$
Replacement : $1$2$3, $1
Here is Online demo
Read more about Java Pattern
Sample code:
String regex = "^([A-Z]+)([0-9]*)(, [0-9]+)?$";
String replacement = "$1$2$3, $1";
String newLine = line.replaceAll(regex,replacement);
For better performance, read 100 or more lines at a time and store in a buffer and finally call String#replaceAll() single time to replace all at a time.
sample code:
String regex = "([A-Z]+)([0-9]*)(, [0-9]+)?(\r?\n|$)";
String replacement = "$1$2$3, $1$4";
StringBuilder builder = new StringBuilder();
int counter = 0;
String line = null;
try (BufferedReader reader = new BufferedReader(new FileReader("abc.csv"))) {
while ((line = reader.readLine()) != null) {
builder.append(line).append(System.lineSeparator());
if (counter++ % 100 == 0) { // 100 lines
String newLine = builder.toString().replaceAll(regex, replacement);
System.out.print(newLine);
builder.setLength(0); // reset the buffer
}
}
}
if (builder.length() > 0) {
String newLine = builder.toString().replaceAll(regex, replacement);
System.out.print(newLine);
}
Read more about Java 7 - The try-with-resources Statement