之前有一个需求是从一个mysql的建表语句中获取表名,即从"create table t_student ...."这个建表语句中获取表名t_student。第一反应肯定是直接利用字符串api处理,找table后面的第一个单词。如果单词分隔符不只是空格还包含\t,\r和\n等,这样匹配起来就有点麻烦了。用正则表达式处理这类问题可能会比较好,直接上代码。
public class TestRegexGroup {
// \\s+ 匹配所有空白
// \\s+create\\s+\\table(\\w+)\\s+
// * 0个或者多个
// + 1个或者多个
private static final Pattern VARIABLE_PATTERN = Pattern
.compile("\\s*[c,C][r,R][e,E][a,A][t,T][e,E]\\s+[t,T][a,A][b,B][l,L][e,E]\\s+(\\w+)\\s+");
public static void main(String[] args){
String sql = "creAte taBle \r\n t_student \r\n (...);";
Matcher matcher = VARIABLE_PATTERN.matcher(sql);
while (matcher.find()) {
System.out.println(matcher.group(0)); // 返回匹配的正则表达式
System.out.println(matcher.group(1)); // 返回匹配第1个"()"的内容
System.out.println("=====================================");
}
}
}
上面代码中的Pattern匹配create table tablename这类字符串,并考虑了"create"和"table"这两个单词的大小写。
找到给定sql中所以匹配给定Pattern的子串(本例中只有一个匹配的子串)。然后通过matcher#group获取表名
matcher.group() 和 matcher.group(0)的功能一样返回整个匹配的子串;
matcher.group(1)返回正则表达式中第1个"()"内的值;
matcher.group(2)返回正则表达式中第2个"()"内的值;
...
本文例子中正则表达式\\s*[c,C][r,R][e,E][a,A][t,T][e,E]\\s+[t,T][a,A][b,B][l,L][e,E]\\s+(\\w+)\\s+中只有一个"()",这个"()"中的内容正好匹配表名,通过matcher.group(1)就可以获得表名了。