求一Jakarta-ORO正则表达式

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

...全文
115 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 bao110908 的回复:]
根据以往回复正则表达式帖子的经验,在给出正则表达式之后楼主八成会提出新的要求。

比如:提出 WHERE 后面有多个条件,可能是用 AND 连接的,也可能是用 OR 连接的。
[/Quote]

这次您可错了哦~~~经验惯性思维,有时候靠不住的哦,嘿嘿。。
阿士匹灵 2009-07-16
  • 打赏
  • 举报
回复
那我就来灌水了

呵呵

看来我正则学的还是不行啊

学习吧

惭愧
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 qingyunzhuimeng 的回复:]
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));
}
}
[/Quote]

你的方法可行,可惜灵活性差了点..
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lgg201 的回复:]
等等, 我再改进下..
[/Quote]

你的方法试过,可行,不过还是等你改进的结果看看,
至少一半的分是你的了~~:)
goosman 2009-07-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 bao110908 的回复:]
根据以往回复正则表达式帖子的经验,在给出正则表达式之后楼主八成会提出新的要求。

比如:提出 WHERE 后面有多个条件,可能是用 AND 连接的,也可能是用 OR 连接的。
[/Quote]


晕, 忘了OR了, 原理是一样的. 楼主自己处理一下吧...
goosman 2009-07-16
  • 打赏
  • 举报
回复
改进了下, 可以检测多个参数了, 不过其他关键字比如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);
}
}
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lgg201 的回复:]
等等, 我再改进下..
[/Quote]

好的,谢谢~~~
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
哇。。。一下好多人响应,感动~~
  • 打赏
  • 举报
回复
根据以往回复正则表达式帖子的经验,在给出正则表达式之后楼主八成会提出新的要求。

比如:提出 WHERE 后面有多个条件,可能是用 AND 连接的,也可能是用 OR 连接的。
tatuotuo1 2009-07-16
  • 打赏
  • 举报
回复
供参考:

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}匹配前面不是小写字母的七位数字(实验时发现错误?注意你的“区分大小写”先项是否选中)。


qingyunzhuimeng 2009-07-16
  • 打赏
  • 举报
回复
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));
}
}
goosman 2009-07-16
  • 打赏
  • 举报
回复
等等, 我再改进下..
zhangpeixv 2009-07-16
  • 打赏
  • 举报
回复
对正则还不太熟悉
不敢献丑
帮顶
呵呵
goosman 2009-07-16
  • 打赏
  • 举报
回复
你再看一看调整一下吧. 感觉还是不太好... 没有加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);
}
}
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
连个来灌水的都没有了?~~
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
。。。貌似会这个的不多呀
beijixing022 2009-07-16
  • 打赏
  • 举报
回复
在线等~~
通过测试者得分

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧