Regex: Pattern to find Java class in .java file

java, regex

Solution

`[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.

Problem

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.

Original source