62,616
社区成员
发帖
与我相关
我的任务
分享
public static void main(String[] a) {
/*
* 首先提取WHERE 子句
*/
//from User u where u.name =:name
StringBuilder str = new StringBuilder("from User u Where u.name =:name AND u.value =:value");
Pattern keyPattern = Pattern.compile("[w[W]][h[H]][e[E]][r[R]][e[E]]");
Matcher keyMatcher = keyPattern.matcher(str.toString());
String key = null;
if(keyMatcher.find()) {
key = keyMatcher.group();
}
if(key == null || key.trim().equals("")) {
return ;
}
/**
* 下面两句插入一个1=1 AND 然后从AND开始截取
* 是为了让HQL的WHERE子句中的有效条件都有一个前置的AND
*/
str.insert(str.indexOf(key, 1) + 5, " 1=1 AND ");
str.delete(0, str.indexOf("AND", 1));
/**
* 经过上面的操作, str已经变成了AND u.name =:name AND u.value =:value
*/
Pattern argPattern = Pattern.compile("[a[A]][n[N]][d[D]](\\s+\\S+\\s*=:\\s*\\S+\\s*)");
Pattern pairPattern = Pattern.compile("(.*)=:(.*)");
Matcher argMatcher = argPattern.matcher(str);
Matcher pairMatcher = null;
Map<String, String> args = new HashMap<String, String>();
while(argMatcher.find()) {
//这里循环匹配得到的argMatcher.group()值
//是AND u.name =:name
//AND u.value =:value
//substring(3) 为了去掉AND
pairMatcher = pairPattern.matcher(argMatcher.group().substring(3));
if(pairMatcher.find()) {
//下面的匹配用=:作为分割, 就可以分出来key和value.
// System.out.println("name: " + pairMatcher.group(1) + ", value: " + pairMatcher.group(2));
args.put(pairMatcher.group(1).trim(), pairMatcher.group(2).trim());
}
}
for(Iterator<String> it = args.keySet().iterator(); it.hasNext();) {
String thisKey = it.next();
String value = args.get(thisKey);
System.err.println("key = " + thisKey + ", value = " + value);
}
}
前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:
/b/w*q[^u]/w*/b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总是匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的/w+/b将会匹配下一个单词,于是/b/w*q[^u]/w*/b就能匹配整个Iraq fighting。负向位置指定能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:/b/w*q(?!u)/w*/b。
零宽负向先行断言(?!exp),只会匹配后缀exp不存在的位置。/d{3}(?!/d)匹配三位数字,而且这三位数字的后面不能是数字。
同理,我们可以用(?<!exp),零宽负向后行断言来查找前缀exp不存在的位置:(?<![a-z])/d{7}匹配前面不是小写字母的七位数字(实验时发现错误?注意你的“区分大小写”先项是否选中)。
public static void main(String[] a) {
//from User u where u.name =:name
String str = "from User u Where u.name =:name";
Pattern argPattern = Pattern.compile("[w[W]][h[H]][e[E]][r[R]][e[E]](\\s+\\S+\\s*=:\\s*\\S+\\s*)");
Pattern pairPattern = Pattern.compile("(.*)=:(.*)");
Matcher argMatcher = argPattern.matcher(str);
Matcher pairMatcher = null;
Map<String, String> args = new HashMap<String, String>();
if(argMatcher.find()) {
pairMatcher = pairPattern.matcher(argMatcher.group(1));
if(pairMatcher.find()) {
// System.out.println("name: " + pairMatcher.group(1) + ", value: " + pairMatcher.group(2));
args.put(pairMatcher.group(1), pairMatcher.group(2));
}
}
for(Iterator<String> it = args.keySet().iterator(); it.hasNext();) {
String key = it.next();
String value = args.get(key);
System.err.println("key = " + key + ", value = " + value);
}
}