要求从字符串"from User u where u.name =:name" 中提取出"u.name =:name";
大家一看就知道是hql语句,呵呵,所以u.name中的“u.”可能有也可能没有,没有的时候提取出"name =:name";

解决方案 »

  1.   

    你再看一看调整一下吧. 感觉还是不太好... 没有加hql中的排序,分组其他操作的验证, 比如你的hql语句后面如果有group by或order by, 就会有错误.这个问题的解决就需要对HQL的语句比较熟悉了, 需要考虑所有的情况.因为在WHERE 子句后面还可以有很多东西.还有一个问题就是如果有多个参数, 比如from User u where u.name =:name AND u.password =:password   不过这个问题比较简单, 你在得到argMatcher.group(1)之后, 再做一次对AND作为pattern的正则, 就可以解决.
    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);
    }
    }
      

  2.   

    Pattern p = Pattern.compile("([u.name =:name]*)([name =:name]*)");
    Matcher m = p.matcher("from User u where u.name =:name");\
    while (m.find()) {
        if (m.group(0) != null) {
           System.out.println(m.group(0));
        }
        if (m.group(1) != null) {
           System.out.println(m.group(1));
        }
    }
      

  3.   

    供参考:http://www.javaeye.com/topic/50548
    前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母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}匹配前面不是小写字母的七位数字(实验时发现错误?注意你的“区分大小写”先项是否选中)。
      

  4.   

    根据以往回复正则表达式帖子的经验,在给出正则表达式之后楼主八成会提出新的要求。比如:提出 WHERE 后面有多个条件,可能是用 AND 连接的,也可能是用 OR 连接的。
      

  5.   

    改进了下, 可以检测多个参数了, 不过其他关键字比如group by 和order by还没有处理能力...原理是一样的.
    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);
    }
    }