Ndifreke
Ndifreke

Reputation: 784

Java Regular Expression to match any method signature

I need to find any kind of Java method signature in a string using regular expression. This is what I have so far an it is not very pretty. The last piece I need help with is implementing case7, Matching method with more than one parameter and also make the regex more concise and readable.

 import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    class MethodMatcher {

public static void main(String[] args) {

    String PARAM_ARG_PATTERN
            = Pattern.quote("(") + 
            "(([\\s]*[a-zA-Z_][\\w\\d]*[\\s]*[a-zA-Z_][\\w\\d]*[\\s]*)|[\\s]*)" 
            + Pattern.quote(")");

    String METHOD_NAME_PATTERN = "[\\s]+[a-zA-Z_][\\w\\d]+[\\s]*";

    String METHOD_PATTERN = METHOD_NAME_PATTERN + PARAM_ARG_PATTERN;

    String case1 = " _validName__ ( _TypeName _variable)";
    String case2 = " 7invalidName (_TypeName variable)";
    String case3 = "badName_ (_pp8p_7 _s5de)";   //method Name has no leading space
    String case4 = " Valid4Name_()";                 //No Parameter ValidName( )
    String case5 = " validName(7BadType variable)";
    String case6 = " validName_(InvalidParam)";     //no variable name
    String case7 = " validName(Type1 arg1, Type2 arg2)"; //but fails need help implementing

    String cases[] = {case1, case2, case3, case4, case5, case6, case7};
    int c = 1;
    Pattern p = Pattern.compile(METHOD_PATTERN);

    for (String strMethod : cases) {
        Matcher m = p.matcher(strMethod);
        if (m.find())
            System.out.println(strMethod + " passed");
        c++;
    }

}

}

Upvotes: 2

Views: 2560

Answers (1)

wp78de
wp78de

Reputation: 18950

This looks more like homework or finger exercise than an actual project. Here is a jumpstart:

^\s*([a-zA-Z_]\w+)\s*(?:\(|\G)(\s*([a-zA-Z_]\w+)\s+([a-zA-Z_]\w+),?)*\)\s*$

Update: The following pattern allows unlimited args (the anchors IMHO not needed):

^\s*(?:^\s*([a-zA-Z_]\w+)\s*\(\s*|\G,\s*)(\s*([a-zA-Z_]\w+)\s+([a-zA-Z_]\w+),?)*\)\s*$

Original demo code:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class T
{
  public static void main(String[] args)
  {

        final String regex = "^\\s*\n" 
                            + "([a-zA-Z_]\\w+)                                    # function name\n" 
                            + "\\s*\n" 
                            + "(?:\\(|\\G)\n" 
                            + "(\\s*([a-zA-Z_]\\w+)\\s+([a-zA-Z_]\\w+),?)*           #args\n" 
                            + "\\)\n" 
                            + "\\s*$";

        final String string = " _validName__ ( _TypeName _variable)\n" 
                            + " 7invalidName (_TypeName variable)\n" 
                            + "badName_ (_pp8p_7 _s5de)\n" 
                            + " Valid4Name_()\n" 
                            + " validName(7BadType variable)\n" 
                            + " validName_(InvalidParam)\n" 
                            + " validName(Type1 arg1, Type2 arg2)";

        final Pattern pattern = Pattern.compile(regex, Pattern.COMMENTS | Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }
    }
}

Updated Demo

Upvotes: 2

Related Questions