原始发表时间:2009-04-05
今天遇到一个需求,是将oracle 的语句替换为hsqldb 的语句,其中oracle 语句中调用了trim 函数,本来想自己写个名为trim 的静态方法而后通过hsqldb 的“create alias” 映射到hsqldb 当中,结果发现hsqldb 中已经将trim 设置为保留字,并且还没有提供实现(晕……不提供功能还站着地方~~ )
思前想后要不然就替换吧,hsqldb 当中有ltrim 和rtrim 这两个函数,我可以将SQL 语句中的trim() 替换为ltrim(rtrim()) 这样不就结了?一瞬间很佩服自己点子来的够快(不过高兴的太早了,后面就进入了梦魇阶段……-_-bbb )
由于trim() 函数中可能会有其他的文本内容,于是乎很自然的想到用正则表达式,pia pia 写好正则表达式进行替换(这个比较简单就不给出代码了),脑袋灵光一闪,突然想到万一有人在trim() 里面写很复杂的语句,或者trim() 函数嵌套使用呢?
比如有人写了这样一些语句:
示例 1 :
trim(case when a=1 then '0' when trim(a)='' or trim(a) is null then '1' else '2' )
示例 2 :
trim(trim(trim(' 123 ')))
看到这个我有一种不祥的预感,翻了一遍Apress 出版的可爱的“小人书”《Java.Regular.Expressions.Taming.the.java.Dot.util.Dot.regex.Engine 》(绝无轻蔑之意,只是这本书写的太漂亮了,所以忍不住取个外号,唉~~ 坏习惯了~~ ),无果……
在网上乱逛帖子,从4 月4 日的晚上到4 月5 日的上午,差不多4 、5 个钟头(不算睡觉、看片、打CS 的时间)都花在这个问题上,突然看到一个关键字“嵌套”(英文nested ),在某个帖子里看到Java 的正则表达式并不支持嵌套匹配,有搜到一篇文章是.Net 中如何实现嵌套匹配的(该文链接为http://blog.csdn.net/appoFeng/archive/2008/07/07/2620998.aspx ),看得我直眼馋,为虾米Java 没有呢?这个可以有啊!!网上帖子一直表示“这个真没有!!”
火大了,在电脑的资料翻电子书,终于翻到另外一件宝贝O'Reilly 的《Mastering.Regular.Expressions 》 2Nd.Edition (网上看到最新的是第三版,该死的网络,要不然我早就拿到第三版了)~~
因为网上讲Perl 也实现了嵌套调用,而且Jakarta-ORO 项目正是实现Perl 的正则表达式引擎的项目,于是乎我又报了一点希望的看ORO 的文档,不过它的文档有够简单的,没办法继续google ,在网上看到的帖子鲜有介绍这方面信息的,目光出溜出溜着回到了《Mastering.Regular.Expressions 》,心里默念,主啊,给个面子,给点提示吧~~ 哥哥我快被你整挂了~~
翻到书中Perl 相关的章节(还好报了最后一点希望,要不然永远不知道还有硬编码这个方法可以实现嵌套匹配的),翻到第7 章的第8 节“Fun With Perl Enhancements” (这个标题真是漂亮,我最爱增强特性了),文字部分就不讲了,大家看看Figure 1. Capturing parentheses ,有没有觉得这张图想什么?我觉得有点像蒙娜丽莎(边想着边躲避面前飞来的板砖),我的意思是这张图就是解决问题的幸运钥匙(比喻的好……像小学生的造句……)
这个图的小节标题是“ 7.8.1 Using a Dynamic Regex to Match Nested Pairs” ,正是让我们使用 Perl 的动态正则表达式匹配成对嵌套的内容(翻译的有点蹩脚 ~~ -_-# )
参考文章的思路,写成了下面的代码,用来将 trim() 函数翻译成 ltrim(rtrim()) 。
public static void main(String[] args) {
String exp = "([^lr])trim" + createExpRecursive("\\(([^()]*|([^()]*", "[^()]*)*)\\)", 3);
System.out.println("生成的正则表达式内容:" + exp);
Pattern pattern = Pattern.compile(exp);
String result = "trim(case \n\twhen a=1 then '0' "
+ "\n\twhen trim(case when a=1 then trim(' 123 ') "
+ "\n\telse trim('abc ') end)='' or trim(b) is null then '1' else '2'"
+ "\n)";
Matcher m = pattern.matcher(result);
while (m.find()) {
for (int i = 0; i < m.groupCount(); i++) {
System.out.println("grp " + i + " :" + m.group(i));
}
result = m.replaceAll("$1ltrim(rtrim($2))");
System.out.println("replaced result step by step: \n----------------\n"
+ result + "\n----------------\n");
m.reset(result);
}
System.out.println("final res: \n----------------\n"
+ result + "\n-----------------\n");
}
private static String createExpRecursive(String start, String end, int depth) {
if (depth == 1) {
return start + "\\([^()]*\\)" + end;
} else {
return start + createExpRecursive(start, end, depth - 1) + end;
}
}
也许大家会纳闷,为虾米正则表达式的开头是 ([^lr]) 其实是为了防止反复匹配替换的时候陷入死循环,因为咱们执行完第一次替换后,会出现 ltrim(rtrim(...)) ,没有这个限定条件的话,会一直不停的进行匹配替换。
另外有个小问题,大家执行的时候会发现第一个 trim 并没有被替换掉,这是因为……(原因简单就不赘述了 ~~ :)),解决的方法是另外再写个正则表达式,只用来匹配以 trim 打头的情况(唉 ~~ 这是我第一反应想到的方法,够白痴吧 ~~ )其实只要你对需要处理的 result 字符串在进行匹配替换之前,在字符串的开端处加上一个空格即可搞掂 ~~
所以方法是无限多,只是偶们还没有想到而已 ~~
分享到:
相关推荐
本篇将围绕“使用Java正则表达式分析处理日志”这一主题,探讨如何利用Java的正则表达式功能来提取、过滤和操作日志数据。 首先,我们需要理解正则表达式的基本概念。正则表达式(Regular Expression)是一种模式...
在Java中,正则表达式主要通过`java.util.regex`包来实现,提供了Pattern和Matcher两个核心类。 **1. Pattern类** Pattern类是Java正则表达式的起点,它将一个正则表达式编译成一个模式对象。这个编译过程可以优化...
在Java中使用正则表达式,通常会使用Java自带的标准库。但在撰写本文时,Java尚未正式支持正则表达式,因此可以通过Jakarta-ORO库来实现。以下是一个简单的使用示例: 1. **加载Jakarta-ORO库**:首先,从Apache...
Java正则表达式匹配工具是IT领域中一种强大的文本处理工具,它利用正则表达式(Regular Expression)的规则来查找、替换或者提取文本中的特定模式。正则表达式是一种特殊的字符序列,能够帮助程序员或者用户高效地...
Java使用正则表达式提取XML节点内容的方法示例主要介绍了Java使用正则表达式提取XML节点内容的方法,结合具体实例形式分析了java针对xml格式字符串的正则匹配相关操作技巧。 一、正则表达式简介 正则表达式是指一...
Java正则表达式是Java语言中用于处理字符串的强大工具,它允许程序员进行复杂的字符串匹配、查找和替换操作。正则表达式(Regular Expression)是一种模式匹配语言,通过特定的语法来描述字符串的模式,用于在文本中...
### 使用Java正则表达式实现一个简单的身份证号码验证 #### 一、背景介绍 身份证号码是中国公民的身份标识,由15位或18位数字组成(早期为15位,后改为18位)。其中,第18位是校验码,可能是数字0~9或者大写字母X。...
Java中的正则表达式主要通过`java.util.regex`包来实现,核心类有`Pattern`和`Matcher`。`Pattern`是编译正则表达式的对象,编译后可以多次使用。`Matcher`对象是实际执行匹配操作的对象,它与输入字符串关联,并...
Java正则表达式验证IP地址是指使用Java语言中的正则表达式来验证IP地址是否符合标准。IP地址是指在网络通信中用来标识设备的地址,它是一种逻辑地址,通过它可以找到网络中的设备。在Java中,可以使用正则表达式来...
使用Java正则表达式的好处在于它能显著提高编程效率,例如验证电子邮件地址这样的任务,传统方法可能需要大量的代码,而使用正则表达式则可以大大简化。然而,这也需要程序员学习和掌握正则表达式相关的知识。 在...
### Java正则表达式匹配全角空格 在Java编程中,处理字符串是非常常见的需求之一。其中,使用正则表达式来对字符串进行拆分、替换等操作是一种非常高效的方法。本文将详细介绍如何使用Java中的`split()`方法,并...
正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、数据提取等IT领域。在这个“常用正则表达式HTML,JAVA合集”中,我们主要关注的是HTML和Java环境下的正则...
java使用正则表达式进行校验验证,主要使用了Pattern和Matcher类,直接main方法运行就可以,亲测有效
Java正则表达式是编程语言Java中的一个强大工具,它用于模式匹配、数据验证和文本检索替换。在Java中,正则表达式是通过java.util.regex包提供的接口和类来实现的。`regex-smart.jar`这个库显然是为了简化开发者在...
Java正则表达式是Java语言中的一种模式匹配技术,用于匹配、查找、替换和判断字符串。它是一种强大的工具,能够帮助开发者快速处理字符串相关的任务。 什么是正则表达式? 正则表达式是一种特殊的字符串,用于描述...
Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许我们通过模式匹配来查找、替换或分割文本。在Android开发中,正则表达式尤其重要,因为它们可以帮助我们验证用户输入、处理文本数据或者进行复杂的...
在 Java 中,使用正则表达式对象可以实现各种字符串匹配和提取操作。正则表达式对象主要通过 Pattern 和 Matcher 两个类来实现。下面详细介绍如何使用正则表达式对象实现正则获取功能。 一、基本概念 在使用正则...
Java正则表达式测试工具是面向开发者和爱好者的一款实用程序,它可以帮助用户验证和调试他们的正则表达式。在Java编程环境中,正则表达式是一个强大的字符串处理工具,广泛用于数据验证、文本搜索和替换等任务。这款...
Java正则表达式 Java 正则表达式 图片版 携带方便,查阅方便!~