2012-02-08 5 views
7

Я хочу проанализировать инструкцию объявления переменной и получить имя переменной. Я делаю нижеregex, чтобы соответствовать объявлению переменной в java

String var = "private String ipaddress;"; 

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

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

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

+1

Просто из любопытства - хотя это может помочь нам еще лучше: в чем прецедент для этого? Чего вы хотите добиться с помощью этого синтаксического анализа? – Thomas

ответ

3

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

+1

. Небольшая коррекция: второе значение z в вашем определении '\ w' должно быть в верхнем регистре. – Thomas

10

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

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

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

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

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

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

Edit:

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

+0

. Точка в начале правильная, так как за ней следует' * ', которая также не будет соответствовать появлению точки. –

+0

@CarlosHeuberger да, теперь он несколько правильный, хотя он будет соответствовать 'barprivate'. Однако, когда я это написал, звездочка отсутствовала (или, по крайней мере, я не видел ее из-за проблем с форматированием) :) – Thomas

+0

ОК и еще одна причина не использовать регулярное выражение для разбора ... –

3

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

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

Это удостоверится, чтобы соответствовать:

  • чувствителен к регистру матча, за исключением ключевого слова private
  • Мульти декларация линия
  • белых пространств при запуске, в середине
+0

это могло бы (возможно, ошибочно) соответствовать 'ЧАСТНЫЙ ...' –

+0

@CarlosHeuberger: Спасибо, обновил ответ. – anubhava

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)); 
} 

Он будет искать любое имя переменной, которая начинается с пробелом и заканчивается либо «;» или "=". Это более общий поиск имени переменной.

EDIT Это один заставил меня думать на самом деле, так как это также юридическое заявление в Java:

private 
static 
volatile 
String 
s , t1 = ""; 

Это на самом деле можно было бы улучшить, вероятно, как это было thinked/сделано быстро.

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

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

Смежные вопросы