Ответ 1
Попробуйте следующее:
(?:(?<=int|float|String|double|char|long)(?:\s+[a-zA-Z_$][\w$]*\s*)|(?<=\G,)(?:\s*[a-zA-Z_$][\w$]*\s*))(?=,|;|=)
что означает:
-
(?<=int|float|String|double|char|long)
- положительный lookbehind поиск типа переменной, -
(?:\s+[a-zA-Z_$][\w$]*\s*)
- не захватывающая группа: по крайней мере одно место, за которым следует действительная символы для переменных Java, за которыми следуют ноль или более пробелов. -
|
- или; альтернатива между именем обработки после var. тип или после запятой, -
(?<=\G,)
- положительный lookbehind для предыдущего совпадения и запятой (потому что другие части соответствуют пробелам с обеих сторон) -
(?:\s*[a-zA-Z_$][\w$]*\s*)
- не захватывающая группа: по крайней мере одно место, за которым следует действительная символы для переменных Java, за которыми следуют ноль или более пробелов. -
(?=,|;|=)
- положительный результат для запятой, знак равенства или полуколония
использует граничное соответствие \G
(Конец предыдущего соответствия), поэтому альтернатива, в которой имена поиска между другими именами ( слова между пробелами или/и запятыми точно), будет соответствовать только в том случае, если это после предыдущего совпадения. Таким образом, он не будет соответствовать каждому слову между запятыми в Strings, например. Также я добавил $
в [a-zA-Z_$][\w$]*
, поскольку разрешено в именах переменных, однако не рекомендуется.
И для Java:
Pattern pattern = Pattern.compile("(?:(?<=int|float|String|double|char|long)(?:\\s+[a-zA-Z_$][\\w$]*\\s*)|(?<=\\G,)(?:\\s*[a-zA-Z_$][\\w$]*\\s*))(?=,|;|=)");
ИЗМЕНИТЬ
Вы можете использовать (int |float |...)
для сопоставления имен переменных напрямую с помощью matcher.start()
и matcher.end()
без пробелов, однако я бы предпочел использовать (?:\s*)
в любом месте, где может быть место, а затем проверять избыточные пространства во время процесса обработки данных, потому что вы никогда не знаете, сколько пробелов будет вводиться пользователем (конечно, более одного избыточно, но оно все еще действует!).
Другим способом было бы сопоставить пробелы, но использовать группы, например:
(?:(?<=int|float|String|double|char|long)(?:\s+)([a-zA-Z_$][\w$]*)(?:\s*)|(?<=\G,)(?:\s*)([a-zA-Z_$][\w$]*)(?:\s*))(?=,|;|=)
имена не имеют пробелов, но вам нужно извлечь их из групп 1 и 2 с помощью matcher.start(group no)
и matcher.end(group no)
.
EDIT2 ответьте на вопрос из комментария
Это зависит от того, чего вы хотите достичь. Если вы просто хотите получить переменные как строки, достаточно использовать mathod trim()
, но если вы хотите получить начальные и конечные индексы переменных в тексте, чтобы, например, выделить его в другом цвете, то лучше использовать его для пример matcher.start(1)
, чтобы извлечь начальный индекс группы 1. Рассмотрим этот пример:
import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) throws IOException {
String text = "int a = 100;\n" +
"float b = 100.10;\n" +
"double c - 12.454545645;\n" +
"long longest dsfsf = 453543543543;\n" +
"a = d;\n" +
"char b = 'a';\n" +
"String str = \"dfssffdsdfsd\"\n" +
"int d,f,g;\n" +
"int a,f,frhg = 0;\n" +
"String string = \"a,b,c,d,e,f\"";
Pattern pattern = Pattern.compile("(?:(?<=int|float|String|double|char|long)(?:\\s+)([a-zA-Z_$][\\w$]*)(?:\\s*)|(?<=\\G,)(?:\\s*)([a-zA-Z_$][\\w$]*)(?:\\s*))(?=,|;|=)");
Matcher matcher = pattern.matcher(text);
while(matcher.find()){
System.out.println("trim(): " + text.substring(matcher.start(),matcher.end()).trim()); // cut off spaces by trim() method;
int group = (matcher.group(1)==null)? 2 : 1; // check which group captured string;
System.out.println("group(" + group + "): \n\t" // to extract string by group capturing;
+ text.substring(matcher.start(group),matcher.end(group))
+ ",\n\tsubstring(" + matcher.start(group) + "," + matcher.end(group)+")");
}
}
}
на выходе присутствуют два совпадения.