`
afei1689
  • 浏览: 16628 次
文章分类
社区版块
存档分类
最新评论

神奇的java正则表达式

阅读更多

项目里用正则表达来匹配解析cookie,表达为: private final static Pattern PATTERN =

        Pattern.compile("(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))");(代码来自开源项目netty的CookieDecoder)

代码上线后,偶尔报错误log: java.lang.StackOverflowError at java.util.regex.Pattern$GroupHead.match(Pattern.java:4166) at java.util.regex.Pattern$Loop.match(Pattern.java:4295) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227) at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078) at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345) at java.util.regex.Pattern$Branch.match(Pattern.java:4114) at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168) at java.util.regex.Pattern$Loop.match(Pattern.java:4295) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227) at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078) at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345) at java.util.regex.Pattern$Branch.match(Pattern.java:4114) at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168) at java.util.regex.Pattern$Loop.match(Pattern.java:4295) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
       很长,略。
 初步认为是请求头的cookie值含有特殊的符号造成stackOverflowError,但把这个出错的cookie的值放在本地机器跑,没有出错,正常解析,更诡异的是,就算是同样的cookie值在线上服务器也是有时候才出错,有时候却完全正常(排除多线程并发的问题,本身java.util.regex.Pattern是线程安全的,另外是单人手工测试,用btrace跟踪确认),如此执行结果不确定,还不说正则本身的性能问题(一字烂),唉!
   线上jdk是sun 64bit jdk1.6_18,正则也是jdk自带的
分享到:
评论
54 楼 无根V稻草 2011-04-14  
诶 一个正则 嵌套这么多层
看上去不累么?
维护不累么?
53 楼 dingoo 2011-04-14  
这个看着头大
52 楼 lord_is_layuping 2011-04-13  
楼主,解决了没,我也遇到一样的问题了,调试模式下没问题,直接执行就报这个异常。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
51 楼 bhdweb 2011-02-15  
对于正则表达式,请记住一句老话:“ 您有一个问题,用正则表达式解决。那您就有两个问题了。” 
50 楼 RonQi 2011-02-15  
hswx_11 写道
看下http://blog.csdn.net/shixing_11/archive/2010/11/09/5997567.aspx;文章
这种正则非常容易形成死循环,这是JDK1.4以来遗留的一个BUG。到JDK1.6也未解决。以后用正则,一定要谨慎,对于大批量的数据校验最好避免正则,SUN对JDK这个BUG有专门说明,请看如下:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507和
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6988218

你给的参考资料很好,受教了。

正在做一个正则表达式,从网页html代码中提出table,
正则:
<table(.|\\n|\\r)*?</table>

在js和一个桌面的正则测试工具下是正常的,能找出给定html字符串的table来,
但在java中当字符串长度超过826时就报栈溢出异常:
Exception in thread "main" java.lang.StackOverflowError
	at java.util.regex.Pattern$CharProperty.match(Pattern.java:3343)
	at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
	......


不知是我的正则有问题还是那个JDK的bug呢
49 楼 RonQi 2011-02-15  
sdh5724 写道
蓝皮鼠 写道
我的正则式不怎么强。但是见过也维护过超复杂的正则式,比如超过几十行的。

经验是正则式最好用于单行简单内容的匹配,如果内容太长的话很难保证有时会出错。

关于StackOverflow原来有次的出错原因是用正则式处理去空白,当空白行太多时正则式写的不好会错。

另外就是对于特殊字符,GBK中的日文等等,有时会导致解析一次几十分钟或者几个小时才能完成。细节原因也没有搞清楚,后来对于这部分自己写解析器搞定了。

最终建议:对于自己能控制的内容,用正则式问题不大。对于未知内容,用正则式有风险,而且比较大。


比较同意你的说法。 我也遇见一些场景是:
1. 在以行处理的参数上, 单行文本太长, 导致性能问题
2. 表达式中包含了换行符, 导致性能问题
3. 大规模使用导致性能问题
4. 占溢出还是递归太多造造成的, 表达式太复杂,导致了深度递归。这个在JDK的表达式实现上比较容易出现, ORO的好象好很多。


受教了。
正在做一个正则表达式,从网页html代码中提出table,
正则:<table(.|\\n|\\r)*?</table>
在js和一个桌面测试的正则工具下是正常的,但在java中当字符串长度超过826时就报栈溢出异常:
Exception in thread "main" java.lang.StackOverflowError
	at java.util.regex.Pattern$CharProperty.match(Pattern.java:3343)
	at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
	......

不知是我的正则有问题还是JDK的bug呢
48 楼 afei1689 2011-01-10  
hswx_11 写道
看下http://blog.csdn.net/shixing_11/archive/2010/11/09/5997567.aspx;文章
这种正则非常容易形成死循环,这是JDK1.4以来遗留的一个BUG。到JDK1.6也未解决。以后用正则,一定要谨慎,对于大批量的数据校验最好避免正则,SUN对JDK这个BUG有专门说明,请看如下:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507和
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6988218

这个回复说到点子上了,如果真是因为某些bug引起死循环,那-Xss设置最大也没有用,最纳闷是,同样的要match的字符串输入并不能保证每次都会抛出StackOverflowError,而是偶尔才会出现,这样使得问题原因更难定位了。
47 楼 hswx_11 2011-01-10  
看下http://blog.csdn.net/shixing_11/archive/2010/11/09/5997567.aspx;文章
这种正则非常容易形成死循环,这是JDK1.4以来遗留的一个BUG。到JDK1.6也未解决。以后用正则,一定要谨慎,对于大批量的数据校验最好避免正则,SUN对JDK这个BUG有专门说明,请看如下:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507和
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6988218
46 楼 sdh5724 2011-01-09  
蓝皮鼠 写道
我的正则式不怎么强。但是见过也维护过超复杂的正则式,比如超过几十行的。

经验是正则式最好用于单行简单内容的匹配,如果内容太长的话很难保证有时会出错。

关于StackOverflow原来有次的出错原因是用正则式处理去空白,当空白行太多时正则式写的不好会错。

另外就是对于特殊字符,GBK中的日文等等,有时会导致解析一次几十分钟或者几个小时才能完成。细节原因也没有搞清楚,后来对于这部分自己写解析器搞定了。

最终建议:对于自己能控制的内容,用正则式问题不大。对于未知内容,用正则式有风险,而且比较大。


比较同意你的说法。 我也遇见一些场景是:
1. 在以行处理的参数上, 单行文本太长, 导致性能问题
2. 表达式中包含了换行符, 导致性能问题
3. 大规模使用导致性能问题
4. 占溢出还是递归太多造造成的, 表达式太复杂,导致了深度递归。这个在JDK的表达式实现上比较容易出现, ORO的好象好很多。
45 楼 sdh5724 2011-01-09  
afunti 写道
xingqiba 写道
对于正则表达式,请记住一句老话:“ 您有一个问题,用正则表达式解决。那您就有两个问题了。” 

呵呵……
正则匹配的确麻烦,但是它的效率真的不高吗?



我对一般的复杂的表达式测试结果大约能到数十万到百万次每秒。 

对于表达式的递归深度, 文本的长度都需要有清醒的认识。

但是, 总是觉得性能很高, 到处滥用, 就有问题了。 曾经REVIEW到过一次请求5000次正则的检查的代码。
无论性能多高, 不能滥用而已。

这玩意的特点就是: 要么一点事情都没有, 突然出现了, 就能打垮整个服务器的CPU.  在生产故障中, 我碰到不少因此正则不合理使用导致服务器压力特别大, 导致崩溃的事情。
44 楼 afunti 2011-01-08  
xingqiba 写道
对于正则表达式,请记住一句老话:“ 您有一个问题,用正则表达式解决。那您就有两个问题了。” 

呵呵……
正则匹配的确麻烦,但是它的效率真的不高吗?
43 楼 spyker 2011-01-08  
rochoc 写道
蓝皮鼠 写道
我的正则式不怎么强。但是见过也维护过超复杂的正则式,比如超过几十行的。

经验是正则式最好用于单行简单内容的匹配,如果内容太长的话很难保证有时会出错。

关于StackOverflow原来有次的出错原因是用正则式处理去空白,当空白行太多时正则式写的不好会错。

另外就是对于特殊字符,GBK中的日文等等,有时会导致解析一次几十分钟或者几个小时才能完成。细节原因也没有搞清楚,后来对于这部分自己写解析器搞定了。

最终建议:对于自己能控制的内容,用正则式问题不大。对于未知内容,用正则式有风险,而且比较大。


严重同意,我也一直有在用正则,正则在处理文本,如果源内容长度可控的情况下是没有问题的,如果你都不知道你要用来检索的内容有多大,不要使用正则,起码不要使用复杂的正则。



精通正则表达式上面 这点已经做了总结了
42 楼 rochoc 2011-01-08  
蓝皮鼠 写道
我的正则式不怎么强。但是见过也维护过超复杂的正则式,比如超过几十行的。

经验是正则式最好用于单行简单内容的匹配,如果内容太长的话很难保证有时会出错。

关于StackOverflow原来有次的出错原因是用正则式处理去空白,当空白行太多时正则式写的不好会错。

另外就是对于特殊字符,GBK中的日文等等,有时会导致解析一次几十分钟或者几个小时才能完成。细节原因也没有搞清楚,后来对于这部分自己写解析器搞定了。

最终建议:对于自己能控制的内容,用正则式问题不大。对于未知内容,用正则式有风险,而且比较大。


严重同意,我也一直有在用正则,正则在处理文本,如果源内容长度可控的情况下是没有问题的,如果你都不知道你要用来检索的内容有多大,不要使用正则,起码不要使用复杂的正则。
41 楼 ouchxp 2011-01-07  
引用
你会来解析一下这是为何,我说的性能,你提的是灵活性,有毛关系。
装*给雷劈就是你这种

引用
不是性能不行 是你不会用. (此处说的是性能问题.)
正则应该用在描述容易改变的规则. 比如文本的搜索条件,输入的校验等.
方便以后规则的更改.(此处说的是适用正则的场合)

我没说我会正则调优.
但是我知道用这么一大堆乱七八糟的正则,来解析一个格式几乎不变的字符串肯定是不恰当的.
正则实际上也是通过循环解析字符串来执行.过多子表达式嵌套造成过多的循环.循环期间对象内存和栈空间不能及时回收.所以才造成了异常.

如果让正则高手来做正则调优肯定会有很大的效率提高.
如果非要正则,我给你的建议,拆分成为多个短正则配合逻辑代码多次匹配.

正则是一个很好的工具. 用不好要怪自己.不要怪工具.
就好比用绷带当治疗 还嫌不给力 就说绷带垃圾?
40 楼 kaneg 2011-01-07  
搞了这么久,楼主怎么不把有问题的cookie贴上来啊?
不告诉我们症状,怎么帮你找出问题的根源?
39 楼 afei1689 2011-01-07  
hatedance 写道
正则这东西稍微长一点就很难看懂,但若不用正则,用什么呢?自己写很多if和循环去判断?更头晕。
我觉得折衷的方案是,不要写很复杂的正则。一步一步来,抽丝剥茧。
比如先写(\w*)=(\w*),然后把第一组和第二租用正则再解析。

如果是要用正则解析cookie,这个表达式:(\w*)=(\w*)明显是有问题的,在某些版本的cookie中,两个双引号以内的value是可以包含=等特殊符号的
38 楼 sdh5724 2011-01-07  
如果楼主对于以上意见都不接受, 也可以忽视以下做法法
1. 废除正则, 自己写分析代码, cookie的解析还是很好做的, 看下规范, 很快的
或者,
2. java -server -Xss2m

楼主, 既然来问问题的, 还是注意下自己的态度
基于你对这个溢出不明白含义, 楼主的jvm的基础有些问题,多看看每个参数的含义, 并且测试下, 让你受益匪浅。
37 楼 hua839 2011-01-07  
没 看懂!
36 楼 hatedance 2011-01-07  
正则这东西稍微长一点就很难看懂,但若不用正则,用什么呢?自己写很多if和循环去判断?更头晕。
我觉得折衷的方案是,不要写很复杂的正则。一步一步来,抽丝剥茧。
比如先写(\w*)=(\w*),然后把第一组和第二租用正则再解析。
35 楼 afei1689 2011-01-07  
yym955 写道
您有一个问题,用正则表达式解决。那您就有两个问题了

呵呵,我们用netty来做一个http server,发现它有现成cookie decoder,直接就用上,也没注意它原来是正则来实现的,出了问题才发现,杯具!

相关推荐

    java正则表达式.zip

    Java正则表达式是Java编程语言中用于处理字符串的强大工具,它基于模式匹配的概念,能够高效地进行文本搜索、替换和解析。在Java中,正则表达式主要通过`java.util.regex`包来实现,提供了Pattern和Matcher两个核心...

    Java使用正则表达式提取XML节点内容的方法示例

    为了帮助开发者更好地掌握Java正则表达式技术,我们提供了一系列的Java正则表达式技巧大全,包括《Java正则表达式技巧大全》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧...

    java正则表达式验证IP地址

    Java正则表达式验证IP地址 Java正则表达式验证IP地址是指使用Java语言中的正则表达式来验证IP地址是否符合标准。IP地址是指在网络通信中用来标识设备的地址,它是一种逻辑地址,通过它可以找到网络中的设备。在...

    java正则表达式匹配工具

    Java正则表达式匹配工具是IT领域中一种强大的文本处理工具,它利用正则表达式(Regular Expression)的规则来查找、替换或者提取文本中的特定模式。正则表达式是一种特殊的字符序列,能够帮助程序员或者用户高效地...

    JAVA正则表达式大全

    以下是对这些文档标题所涉及的Java正则表达式知识点的详细解释: 1. **正则表达式之道** 这个主题可能涵盖了正则表达式的基础概念,包括元字符、字符类、量词和分组。元字符如`.`代表任意字符,`^`表示行首,`$`...

    Java正则表达式.ppt

    Java正则表达式是一种强大的文本处理工具,广泛用于验证字符串、查找特定模式和替换文本。在Java中,正则表达式提供了简洁而灵活的方式来处理字符串,使得编程人员能够以更高效的方式实现各种文本操作。 正则表达式...

    使用Java正则表达式分析处理日志

    本篇将围绕“使用Java正则表达式分析处理日志”这一主题,探讨如何利用Java的正则表达式功能来提取、过滤和操作日志数据。 首先,我们需要理解正则表达式的基本概念。正则表达式(Regular Expression)是一种模式...

    Java正则表达式 Java 正则表达式

    Java正则表达式是Java语言中用于处理字符串的强大工具,它允许程序员进行复杂的字符串匹配、查找和替换操作。正则表达式(Regular Expression)是一种模式匹配语言,通过特定的语法来描述字符串的模式,用于在文本中...

    java 正则表达式应用jar包 regex-smart.jar

    Java正则表达式是编程语言Java中的一个强大工具,它用于模式匹配、数据验证和文本检索替换。在Java中,正则表达式是通过java.util.regex包提供的接口和类来实现的。`regex-smart.jar`这个库显然是为了简化开发者在...

    Java 正则表达式 图片版

    Java正则表达式 Java 正则表达式 图片版 携带方便,查阅方便!~

    常用java正则表达式

    ### 常用Java正则表达式知识点 #### 一、引言 正则表达式是一种强大的工具,用于处理文本并查找模式。多种编程语言,包括Perl、PHP、Python、JavaScript以及Java等均内置了对正则表达式的支持。本文将详细介绍Java...

    使用Java正则表达式实现一个简单的身份证号码验证

    ### 使用Java正则表达式实现一个简单的身份证号码验证 #### 一、背景介绍 身份证号码是中国公民的身份标识,由15位或18位数字组成(早期为15位,后改为18位)。其中,第18位是校验码,可能是数字0~9或者大写字母X。...

    Java正则表达式测试工具

    Java正则表达式测试工具是面向开发者和爱好者的一款实用程序,它可以帮助用户验证和调试他们的正则表达式。在Java编程环境中,正则表达式是一个强大的字符串处理工具,广泛用于数据验证、文本搜索和替换等任务。这款...

    Java 正则表达式库

    Java正则表达式库是Java开发中不可或缺的一部分,它为开发者提供了一种强大的文本匹配工具。在Java中,正则表达式(Regular Expression)是一种模式匹配语言,用于处理字符串操作,如查找、替换或提取特定模式的数据...

    Java正则表达式应用总结

    Java正则表达式是编程语言Java中用于处理字符串和文本的强大工具。它允许开发者通过模式匹配来执行复杂的文本分析和操作。在Java中,正则表达式的操作主要涉及两个核心类:`java.util.regex.Matcher`和`java.util....

    java正则表达式使用例子

    Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许我们通过模式匹配来查找、替换或分割文本。在Android开发中,正则表达式尤其重要,因为它们可以帮助我们验证用户输入、处理文本数据或者进行复杂的...

    Java正则表达式详细讲解

    Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许程序员通过模式匹配来查找、替换或分割文本。在Java中,正则表达式是通过`java.util.regex`包提供的API来实现的。本讲解将深入探讨Java正则表达式的...

    Java正则表达式_动力节点Java学院整理

    Java正则表达式详解 Java正则表达式是Java语言中的一种模式匹配技术,用于匹配、查找、替换和判断字符串。它是一种强大的工具,能够帮助开发者快速处理字符串相关的任务。 什么是正则表达式? 正则表达式是一种...

    Java正则表达式详解(非常适合入门

    ### Java正则表达式详解 #### 一、正则表达式的重要性及应用 正则表达式,作为一种强大的文本处理工具,对于程序员而言是不可或缺的基本技能之一。它在文本的匹配、搜索和替换等方面发挥着不可替代的作用。尤其在...

Global site tag (gtag.js) - Google Analytics