регулярное выражение для соответствия объявления переменной в Java - PullRequest
7 голосов
/ 08 февраля 2012

Я хочу разобрать оператор объявления переменной и получить имя переменной. Я делаю ниже

String var = "private   String   ipaddress;";

Я использую шаблон регулярного выражения ниже, чтобы соответствовать строке выше

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

Это не работает. Там написано, что совпадений не найдено. Может ли кто-нибудь помочь, пожалуйста.

Ответы [ 5 ]

10 голосов
/ 08 февраля 2012

Прежде всего, удалите эту точку из начала регулярного выражения, поскольку для совпадения требуется символ перед private.

Во-вторых, ваше регулярное выражение чувствительно к регистру и не будет соответствовать заглавным s. Либо используйте [a-zA-Z], либо сделайте выражение нечувствительным к регистру ((?i) в начале IIRC).

Кстати, [a-zA-Z0-9_] будет таким же, как \w.

Другое дело: ваше выражение будет также ловить недопустимые имена переменных, а также пропускать допустимые имена. Переменные не могут начинаться с цифры, но они также могут содержать знаки доллара. Таким образом, выражение имени должно быть чем-то вроде ([a-zA-Z_$][\w$]*), означая, что первый символ должен быть буквой, подчеркиванием или знаком доллара, за которым следует любое количество символов слова или знака доллара.

Последнее замечание: в зависимости от того, что вы делаете с этими объявлениями, имейте в виду, что вам, возможно, придется проверить эти зарезервированные слова. Например, скорректированное выражение все равно будет соответствовать "private String private".

Еще одно последнее замечание: имейте в виду, что для переменной может быть больше модификаторов, чем private, например public, protected, static и т. Д. - или вообще ничего.

Редактировать

Теперь, когда у вас есть звездочка после первой точки, это не должно быть проблемой для вашего особого случая. Тем не менее, точка соответствует практически любому символу и, следовательно, будет соответствовать fooprivate. В зависимости от того, чего вы хотите достичь, удалите точку или добавьте \s+ после .*.

5 голосов
/ 08 февраля 2012

Поскольку объявление переменной в 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;
}
3 голосов
/ 08 февраля 2012

Посмотрите шаблоны регулярных выражений Checkstyle для соглашений об именах (типы, методы, пакеты и т. Д.). Подробнее здесь .

3 голосов
/ 08 февраля 2012

Вы должны использовать это регулярное выражение:

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

Это обязательно совпадет:

  • Нечувствительное к регистру совпадение, кроме ключевого слова private
  • Многострочныйобъявления
  • пробелы в начале, конце и в середине
3 голосов
/ 08 февраля 2012

.*private\\s+(\\w*)\\s+(\\w*);
используйте этот шаблон. [a-z] - это строчная буква, но «Строка» в вашем тексте начинается с прописной буквы S. \\w - это символ слова. Это так же, как [a-zA-Z0-9_]
Кажется, что ваши тексты будут похожи на "private <type> <field name>;", и если это так, ваш тип может содержать строчные буквы, цифры или подчеркивания, поэтому написание \\w является хорошим решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...