通过字符串

时间:2015-07-30 18:32:37

标签: java regex variables

我正在使用JTextPane创建一个简单的IDE,并检测关键字并对其着色。

目前,我能够检测到:

  1. 评论
  2. 字符串文字
  3. 整数&浮
  4. 关键字
  5. 我检测这些类型的方式是通过正则表达式。

    现在,我正在尝试检测像[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?
    }
    

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

    enter image description here

    在检测到ab等后,我如何能够检测cintfloat等变量?

3 个答案:

答案 0 :(得分:3)

您是否尝试过lookbehind / lookahead模式?

这种漫长的模式:

"(?<=int |float |String |double )([a-zA-Z_]\\w*)(?=,|;|\\s)|([a-zA-Z_]\\w*)(?=,|;|\\s*=)"

能够解析变量和逗号分隔的变量。

public static void main(String[] args) throws Exception {
    String javaCode = "int a = 100;\n" + 
            "float b = 110;\n" + 
            "String c = \"Hello World\";" +
            "double d, e, f, g = 1.0, h;";

    Matcher matcher = Pattern
            .compile("(?<=int |float |String |double )([a-zA-Z_]\\w*)(?=,|;|\\s)|([a-zA-Z_]\\w*)(?=,|;|\\s*=)")
            .matcher(javaCode);
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

结果:

a
b
c
d
e
f
g
h

此处也在regex101

进行了测试

答案 1 :(得分:3)

试试这个:

(?:(?<=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) - 积极向后看 搜索变量类型,
  • (?:\s+[a-zA-Z_$][\w$]*\s*) - 非捕获组:至少一个空格,后跟有效 Java变量的字符,后跟零个或多个空格
  • | - 或; var之后加工名称之间的替代方案。输入或逗号后,
  • (?<=\G,) - 前一场比赛和逗号的正面观察(因为其他部分与两边的空格匹配)
  • (?:\s*[a-zA-Z_$][\w$]*\s*) - 非捕获组:至少一个空格,后跟有效 Java变量的字符,后跟零个或多个空格
  • (?=,|;|=) - 逗号,等号或分号的正面预测

它使用\G边界匹配(The end of the previous match),所以替代方法,即在其他名称之间搜索名称(确切地说是空格或/和逗号之间的单词),只有在它之后才匹配比赛。因此,它不会匹配字符串中逗号之间的每个单词。另外,我在$中添加了[a-zA-Z_$][\w$]*,因为它是变量名中的allowed,但不建议这样做。

DEMO

对于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*)然后检查数据处理过程中的冗余空间,因为你永远不会知道用户输入多少空格(当然多个空间是多余的,但它仍然有效!)。

另一个approuch是匹配空格但使用组,例如:

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

DEMO

名称没有空格,但您需要从第1组和第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)+")");

        }
    }
}

输出呈现两个方法。

答案 2 :(得分:0)

\b(?:int|float|String|char|double|long)\b\s+([^=;]+)

您是否尝试仅匹配变量名称?如果是,则上述内容将有所帮助。