Reputation: 260
I want to find a class' name when reading through a .java file. I'm returning no match right now using this regular expression:
\\s*[public][private]\\s*class\\s*(\\w*)\\s*\\{
Here is my code so far:
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class HW4Solution {
public static void main(String [] args){
//Prompt user for path to file.
File file = null;
Scanner pathScan = new Scanner(System.in);
while (file == null || !file.exists())
{
System.out.print("Enter valid file path: ");
file = new File(pathScan.next());
}
pathScan.close();
System.out.println("File: " + file.getPath() + " found.");
//Read file line by line into buffered reader
StringBuffer componentString = new StringBuffer(100);
String currentLine;
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(file.getPath()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//TODO: Find class declarations
//TODO: Find superclasses
//TODO: Find instance variable declarations
//TODO: Find method signatures
//TODO: Find access modifier
//TODO: Find return type
//TODO: Find method name
//Creating patterns to look for!
//Class declarations
Pattern classDeclarationPattern = Pattern.compile("\\s*[public][private]\\s*class\\s*(\\w*)\\s*\\{");
try {
while((currentLine = bufferedReader.readLine()) != null){
Matcher classDeclarationMatcher = classDeclarationPattern.matcher(currentLine);
if(classDeclarationMatcher.group(1) != null){
componentString.append("Found class declaration: " + classDeclarationMatcher.group(3) + "\n");
/*if(classDeclarationMatcher.group(5) != null){
componentString.append("\tsuperclass: " + classDeclarationMatcher.group(5) + "\n");
}*/
System.out.println(classDeclarationMatcher.group());
}
}
}
catch (IOException e) {
e.printStackTrace();
}
finally{
try{
if (bufferedReader !=null) {
bufferedReader.close();
}
}
catch(IOException e){
e.printStackTrace();
}
}
System.out.println(componentString.toString());
}
}
I eventually want to be able to determine if a class declaration has a superclass and get that too but for now I'm having enough trouble (which I shouldn't) getting the name of the class.
Upvotes: 2
Views: 6785
Reputation: 137
RegExp for class declaration:
private String classRegExp = "(((|public|final|abstract|private|static|protected)(\\s+))?(class)(\\s+)(\\w+)(<.*>)?(\\s+extends\\s+\\w+)?(<.*>)?(\\s+implements\\s+)?(.*)?(<.*>)?(\\s*))\\{$";
for interface declaration:
private String interfaceRegExp = "(((|public|final|abstract|private|static|protected)(\\s+))?interface(\\s+)(\\w+)(<.*>)?(\\s+extends\\s+\\w+)?(<.*>)?(\\s+implements\\s+)?(.*)?(<.*>)?(\\s*))\\{$";
for enum declaration :
private String enumRegExp = "((((public|final|private|static|protected)(\\s+))?enum(\\s+)(\\w+)?(\\s+implements\\s+\\w+)?(.*)?\\s*))\\{$";
Upvotes: 1
Reputation: 213311
[public]
is not matching what you think it should. It is a character class, which matches either of those characters in public
. You should use pipe
to match alternate words.
You can use following regex, extended to consider super
classes or interface: -
Pattern.compile("\\s*(public|private)\\s+class\\s+(\\w+)\\s+((extends\\s+\\w+)|(implements\\s+\\w+( ,\\w+)*))?\\s*\\{");
Note that, you should use \\s+
with +
quantifier when matching space between public|private
and the class
keyword. Because you expect at least 1
space there. \\s*
will match 0
space, which is not correct, since publicclass
is not valid.
Apart from that, there can be some more options to consider here. Like static inner classes
, or generic classes
, that will require minor modification in there, which you can do on your own. I've just given a little insight on to how to approach.
Also, one more important thing. Before you can get the result from your group, you should call Matcher#find()
method to do the actual matching.
Upvotes: 12