我正在使用JTextPane创建一个简单的IDE,并检测关键字并对其着色。
目前,我能够发现:
我检测这些类型的方式是通过正则表达式。
现在,我正在尝试检测诸如int x =10这样的变量,并将它们着色为不同的颜色。
目前,我可以使用以下regex获取所有数据类型,如int、float:
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?
}下面是我的程序的示例输出:

在我检测到a、b、c等变量之后,如何能够检测到int、float等变量?
发布于 2015-07-30 22:48:35
试试这个:
(?:(?<=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*) -非捕获组:至少有一个空格,后面是有效字符,后面是零或多个空格| -或;在var之后的机器名称之间进行选择。键入逗号或逗号后,(?<=\G,) -对以前的匹配和逗号进行正向查找(因为来自两边的其他部分匹配空间)(?:\s*[a-zA-Z_$][\w$]*\s*) -非捕获组:至少有一个空格,后面是有效字符,后面是零或多个空格(?=,|;|=) -逗号、等号或分号的正前瞻它使用\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*))(?=,|;|=)");编辑
您可以使用(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*))(?=,|;|=)名称没有空格,但需要通过matcher.start(group no)和matcher.end(group no)从第1组和第2组中提取它们。
EDIT2从评论中回答问题
这取决于你想要实现什么。如果您只想将变量作为字符串,使用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)+")");
}
}
}输出有两种方式。
发布于 2015-07-30 19:10:03
你试过回头/前瞻模式了吗?
这种长得离谱的模式:
"(?<=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
https://stackoverflow.com/questions/31731479
复制相似问题