正则表达式必须做预编译

24 篇文章 0 订阅

错误案例

现象描述:据校长的观察, Java5的正则表达式的实现可能会导致JVM的崩溃;在递归处理上性能极度低下


错误分析

错误原因: 1、Java5 自身带的实现,没有执行事实上perl标准,导致很多书写方式上和perl的表达不一样, 导致学习成本高 2、已经明确的观察到,Java5的实现可能会导致JVM的崩溃。 3、在深度递归处理下性能很差 4、正则表达式在运行期编译很耗费性能,我们可以看Perl5Compiler().compile方法有差不多200行的代码,都是在做编译工作。

以下是一个错误的例子:每次需要用正则去匹配的时候,都需要把pattern编译一遍,导致性能低下

  private static final String LOGINID_REGEX = "^[a-zA-Z]+[a-zA-Z0-9]+";
  ....
  if (!Pattern.compile(LOGINID_REGEX).matcher(resultStr).find()) {
    ...
  }

正确用法

正确用法: 1. 建议使用ORO库来处理这类问题。 2. 不要使用大规模长度的表达式, 比如根据配置文件的字符串, 拼接成一个非常长的表达式。 这个会导致匹配性能非常的低下。 3. 表达式一定要求是预先编译的, 这个编译过程是非常具有消耗性能的。 4. 如果一些是非频繁的使用的表达预先编译可能在代码的处理上会有点麻烦, 不过, ORO提供给我们一个比较好的util实现:Perl5Util, 他能在cache住一些经常被使用的表达式。 不过大约就是20个样子。 更多http://sdh5724.javaeye.com/blog/277352

  private final static Pattern pattern = new Perl5Compiler().compile("^\\d+$", '''Perl5Compiler.READ_ONLY_MASK''');
  //请注意,由于Pattern本身不是线程安全的,只有加了READ_ONLY_MASK的编译参数才能用于共享使用,否则会出现并发访问的问题,导致错误结果

  public void mach(){
    PatternMatcher matcher = new Perl5Matcher();
    if (matcher.matches(str, pattern)) { …… }
  }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值