正则表达式匹配java中的变量声明

时间:2012-02-08 07:37:55

标签: java regex

我想解析变量声明语句并获取变量名称。我正在做以下

String var = "private   String   ipaddress;";

我使用下面的正则表达式匹配上面的字符串

.*private\\s+([a-z]*)\\s+([a-z0-9_]*);

它不起作用。它说找不到匹配任何人都可以帮忙。

5 个答案:

答案 0 :(得分:10)

首先,从正则表达式的开头删除该点,因为它需要private之前的字符才能匹配。

其次,你的正则表达式区分大小写,与大写字母不匹配。使用[a-zA-Z]或使表达式不区分大小写({II}起始时为(?i))。

顺便说一下,[a-zA-Z0-9_]\w相同。

另一件事:你的表达式也会捕获非法变量名称以及错过合法变量名称。变量不允许以数字开头,但也可以包含美元符号。因此,名称表达式应该类似于([a-zA-Z_$][\w$]*),这意味着第一个字符必须是字母,下划线或美元符号,后跟任意数量的单词字符或美元符号。

最后一点:根据您对这些声明所做的操作,请记住您可能需要检查这些保留字。例如,调整后的表达式仍将匹配"private String private"

另一个最后一点:请记住,对于变量,可能有比private更多的修饰符,例如publicprotectedstatic等等 - 或者根本没有。

修改

现在您在第一个点后面有星号,这对于您的特殊情况应该不是问题。但是,点几乎匹配任何字符,因此也匹配fooprivate。根据您要实现的目标,移除点或在\s+后添加.*

答案 1 :(得分:5)

由于Java中变量的声明可以在变量名之前有3个单词,我建议你不要限制你的搜索并使用它:

String var = "private   String   ipaddress;";
//String var2 = "private static final int test=13;";

Pattern p = Pattern.compile(".+\\s(.+?)(;|=)");
Matcher m = p.matcher(var);

while(m.find()){
    System.out.println(m.group(1));
}

它将查找以空格开头并以“;”结尾的任何变量名称或“=”。这是对变量名称的更一般搜索。

编辑这个让我想到了,因为这也是Java中的法律声明:

private
static
volatile
String
s , t1 = "";

这实际上可能会因为它被快速思考/完成而得到改善。

public static void main(String[] args) {
String var0 = "private static final int test,test2;";
String var1 = "private \n static \n final \n int \n testName \n =\n   5 \n";
String var2 = "private \n static \n final \n String \n testName \n =\n  \" aaa           = bbbb   \" \n";
String var3 = "private \n static \n final \n String \n testName,testName2 \n =\n  \" aaa           = bbbb   \" \n";

String var4 = "int i;";
String var5 = "String s ;";
String var6 = "final String test ;  ";
String var7 = "public int go = 23;";
String var8 = "public static final int value,valu2 ; ";
String var9 = "public static final String t,t1,t2 = \"23\";";
String var10 = "public \n static \n final \n String s1,s2,s3 = \" aaa , bbb, fff, = hhh = , kkk \";";
String var11 = "String myString=\"25\"";

LinkedList<String> input = new LinkedList<String>();
input.add(var0);input.add(var1);input.add(var2);input.add(var3);input.add(var4);input.add(var5);
input.add(var6);input.add(var7);input.add(var8);input.add(var9);input.add(var10);
input.add(var11);

LinkedList<String> result = parametersNames(input);
for(String param: result){
    System.out.println(param);
}

}

private static LinkedList<String> parametersNames(LinkedList<String> input){
LinkedList<String> result = new LinkedList<String>();
for(String var: input){

    if(var.contains("\n")) var = var.replaceAll("\n", "");
    var = var.trim();
    if(var.contains("=")){
        var = var.substring(0, var.indexOf("=")).trim() + "";
        Pattern p = Pattern.compile(".+\\s(.+)$");
        Matcher m = p.matcher(var);

       if(m.find()){
        if(m.group(1).contains(",")){
            String [] tokens = m.group(1).split(",");
            for(String token : tokens){
            result.add(token);
            }
        } else{
            result.add(m.group(1));
        }
        }

    } else{
        Pattern p = Pattern.compile(".+\\s(.+?)(;|=)");
        Matcher m = p.matcher(var);

        if(m.find()){
        if(m.group(1).contains(",")){
            String [] tokens = m.group(1).split(",");
            for(String token : tokens){
            result.add(token);
            }
        } else{
            result.add(m.group(1));
        }
        }
    }
}

return result;
}

答案 2 :(得分:3)

.*private\\s+(\\w*)\\s+(\\w*);
使用这种模式。 [a-z]是一个小写字母,但文本中的“String”以大写S开头。 \\w是一个单词角色。它与[a-zA-Z0-9_]相同 您的文本似乎与"private <type> <field name>;"类似,如果是这样,您的类型可以包含大写的小写字母,数字或下划线,因此编写\\w是一个很好的解决方案。

答案 3 :(得分:3)

你应该使用这个正则表达式:

^(?s)\\s*private\\s+(\\w+)\\s+(\\w+)\\s*;\\s*$

这将确保匹配:

  • 除关键字private
  • 之外的不区分大小写的匹配项
  • 多行声明
  • 开始,结束和中间的空白

答案 4 :(得分:3)

查看Checkstyle正则表达式模式的命名约定(类型,方法,包等)。更多信息here