通过字符串检测变量

use*_*291 12 java regex variables

我正在创建一个简单的IDE使用JTextPane和检测关键字并着色它们.

目前,我能够检测到:

  1. 评论
  2. 字符串文字
  3. 整数和浮点数
  4. 关键词

我检测这些类型的方式是通过正则表达式.

现在,我试图检测像[int x = 10;] 这样的变量并将它们着色为不同的颜色.

目前,我能够使用以下正则表达式获取所有数据类型,如int,float char:

Pattern words = Pattern.compile(\\bint\\b|\\bfloat\\b\\bchar\\b);
Matcher matcherWords = words.matcher(code);
while (matcherWords.find()) {
    System.out.print(code.substring(matcherWords.start(), matcherWords.end());
    // How to get next word that is a variable?
}
Run Code Online (Sandbox Code Playgroud)

以下是我的程序的示例输出:

在此输入图像描述

我怎么能够检测变量一样a,b,c之后我能察觉int,float等等?

m.c*_*era 3

试试这个:

(?:(?<=int|float|String|double|char|long)(?:\s+[a-zA-Z_$][\w$]*\s*)|(?<=\G,)(?:\s*[a-zA-Z_$][\w$]*\s*))(?=,|;|=)
Run Code Online (Sandbox Code Playgroud)

意思是:

  • (?<=int|float|String|double|char|long)- 正向后查找变量类型,
  • (?:\s+[a-zA-Z_$][\w$]*\s*)- 非捕获组:至少一个空格,后跟 Java 变量的有效字符,后跟零个或多个空格
  • |- 或者; var 后的机械名称之间的替代。在逗号后键入 或,
  • (?<=\G,)- 前一个匹配和逗号的正向后查找(因为其他部分匹配两侧的空格)
  • (?:\s*[a-zA-Z_$][\w$]*\s*)- 非捕获组:至少一个空格,后跟 Java 变量的有效字符,后跟零个或多个空格
  • (?=,|;|=)- 逗号、等号或分号的正向前瞻

它使用\G边界匹配(上一个匹配的结尾),因此另一种方法是在其他名称之间搜索名称(空格或/和逗号之间的单词),只有在上一个匹配之后才会匹配。因此,它不会匹配字符串中逗号之间的每个单词。我还添加了$它,[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*))(?=,|;|=)");
Run Code Online (Sandbox Code Playgroud)

编辑

您可以使用直接使用或不使用空格(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*))(?=,|;|=)
Run Code Online (Sandbox Code Playgroud)

演示版

名称不带空格,但您需要通过matcher.start(group no)和从组 1 和 2 中提取它们matcher.end(group no)

编辑2回答评论中的问题

这取决于您想要实现什么目标。如果您只想获取字符串形式的变量,那么使用 mathod 就足够了trim(),但是如果您想获取文本中变量的开始和结束索引,例如以不同的颜色突出显示它,那么最好使用例如matcher.start(1)提取组 1 的起始索引。考虑以下示例:

导入java.io.IOException;导入java.util.regex.Matcher;导入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)+")");

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出呈现两种方法。