概述

做日志分析工作的经常需要跟成千上万的日志条目打交道,为了在庞大的数据量中找到特定模式的数据,常常需要编写很多复杂的正则表达式。例如枚举出日志文件中不包含某个特定字符串的条目,找出不以某个特定字符串打头的条目,等等。

使用否定式前瞻

正则表达式中有前瞻(Lookahead)和后顾(Lookbehind)的概念,这两个术语非常形象的描述了正则引擎的匹配行为。需要注意一点, 正则表达式中的前和后和我们一般理解的前后有点不同。一段文本,我们一般习惯把文本开头的方向称作“前面”,文本末尾方向称为“后面”。但是对于正则表达式引擎来说,因为它是从文本头部向尾部开始解析的(可以通过正则选项控制解析方向),因此对于文本尾部方向,称为“前”,因为这个时候,正则引擎还没走到那块,而对文本头部方向,则称为“后”,因为正则引擎已经走过了那一块地方。如下图所示:

所谓的前瞻就是在正则表达式匹配到某个字符的时候,往“尚未解析过的文本”预先看一下,看是不是符合/不符合匹配模式,而后顾,就是在正则引擎已经匹配过的文本看看是不是符合/不符合匹配模式。符合和不符合特定匹配模式我们又称为肯定式匹配和否定式匹配

现代高级正则表达式引擎一般都支持都支持前瞻,对于后顾支持并不是很广泛,因此我们这里采用否定式前瞻来实现我们的需求。

实现

测试数据:

2009-07-07 04:38:44 127.0.0.1 GET /robots.txt
2009-07-07 04:38:44 127.0.0.1 GET /posts/robotfile.txt
2009-07-08 04:38:44 127.0.0.1 GET /

例如上面这几条简单的日志条目,我们想实现两个目标:

1. 把8号的数据过滤掉

2. 把那些不包含robots.txt字符串的条目给找出来(只要Url中包含robots.txt的都给过滤掉)。

前瞻的语法是:

(?!匹配模式)

我们先来实现第一个目标——匹配不以特定字符串开头的条目

这里我们因为要排除一段连续的字符串,因此匹配模式非常简单,就是2009-07-08。实现如下:

^(?!2009-07-08).*?$

Expresso我们可以看到结果确实过滤掉8号的数据。

接下来,我们来实现第二个目标——排除包含特定字符串的条目

按照我们上面写法,我照葫芦画瓢了一下:

^.*?(?!robots\.txt).*?$

这段正则用大白话描述就是:开头任意字符,然后后面不要跟着robots.txt连续字符串,然后再跟着任意个字符,字符串结尾。

运行测试,结果发现:

没有达到我们想要的效果。这是为什么呢?我们给上面的正则表达式加上两个捕获分组调试一下:

^(.*?)(?!robots\.txt)(.*?)$

测试结果:

我们看到,第一个分组啥都没有匹配到,而第二个分组却匹配了整个字符串。再回过头来好好分析一下刚才那个正则表达式。实际上,当正则引擎解析到A区 域的时候,就已经开始执行B区域的前瞻工作。这个时候发现当A区域为Null的时候匹配成功——.*本来就允许匹配空字符,前瞻条件又满足,A区域后面紧 跟着的是“2009”字符串,而并不是robots。因此整个匹配过程成功匹配到所有条目。

分析出原因之后我们对上述的正则进行修正,将.*?移入前瞻表达式,如下:

^(?!.*?robots).*$

测试结果:

Bingo!

原文出处:点击前往

java正则:不包含某个规则字符串【转】的更多相关文章

  1. java 正则匹配空格字符串 正则表达式截取字符串

    java 正则匹配空格字符串 正则表达式截取字符串 需求:从一堆sql中取出某些特定字符串: 比如配置的sql语句为:"company_code = @cc and project_id = ...

  2. java中如何判断一个字符串是否包含另外一个字符串的方法

    indexOf(String s)的使用,如果包含,返回的值是包含该子字符串在父类字符串中起始位置: 如果不包含必定全部返回值为-1 package my_automation; public cla ...

  3. Java正则速成秘籍(一)之招式篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  4. Java正则速成秘籍(二)之心法篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  5. Java正则速成秘籍(三)之见招拆招篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  6. java正则匹配

    java正则提取需要用到Matcher类,下面给出案例示例供参考 需要提取车牌号中最后一个数字,比如说:苏A7865提取5,苏A876X提取6import java.util.regex.Matche ...

  7. Java 对象,数组 与 JSON 字符串 相互转化

    当 Java 对象中包含 数组集合对象时,将 JSON 字符串转成此对象. public class Cart{} public class MemberCoupon{} public class C ...

  8. js 正则学习小记之匹配字符串

    原文:js 正则学习小记之匹配字符串 今天看了第5章几个例子,有点收获,记录下来当作回顾也当作分享. 关于匹配字符串问题,有很多种类型,今天讨论 js 代码里的字符串匹配.(因为我想学完之后写个语法高 ...

  9. url 中非法字符替换,java 正则替换

    url在传输时不允许的一些字符串,参考自:http://www.ietf.org/rfc/rfc1738.txt 以下字符用java正则替换为"_",一句话搞定: "{& ...

随机推荐

  1. 团队作业4——第一次项目冲刺(Alpha版本)2017.11.16

    1.当天站立式会议照片 本次会议在5号公寓3楼召开,本次会议内容:①:熟悉每个人想做的模块.②:根据老师的要求将项目划分成一系列小任务.③:在上次会议内容完成的基础上增加新的任务. 2.每个人的工作 ...

  2. excel表格如何限制单元格输入内容

    一天一天实在太快,周六了~~~ 测试任务不太紧的时候就可以着手开始整理本月的测试项目,选择的是excel,清晰明了. 原来excel的功能远比我们想象的强大与好用,今天先介绍如何限制单元格内容: 如下 ...

  3. express入门学习(一)

    一.安装express cnpm || npm  install express --save ; 1. Hello  World var express = require('express'); ...

  4. Oracle 默认的driectory 目录

    1. 写导出命令忘记加directory参数了.. 查了一下: select directory_path from all_directories c:\cwdata\ C:\app\Adminis ...

  5. php手册 | python手册 | perl手册 | c#.net手册 | c++手册 | ruby手册 | jquery手册 | js手册 | prototype手册 | mysql手册 | smarty手册 | css手册 | html手册 | nginx手册 | apache手册 | shell手册 | svn手册

    收集各种实用类手册: http://shouce.jb51.net/shell/

  6. Django知识总汇

    基础 Django基础 Django基本命令 model系统 ORM基础 ORM字段和参数 ORM对数据库操作 ORM中介模型 ORM之其他骚操作 templates系统 模板语言 views系统 视 ...

  7. 内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理][转载]

    http://www.cnblogs.com/JCSU/articles/1051579.html 一. 在c中分为这几个存储区1.栈 - 由编译器自动分配释放2.堆 - 一般由程序员分配释放,若程序 ...

  8. ySQL性能优化的21个最佳实践 和 mysql使用索引

    MySQL性能优化的21个最佳实践 和 mysql使用索引 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 ...

  9. [Offer收割]编程练习赛23-freeloop

    A. H国的身份证号码I dfs裸题. 时间复杂度\(O(n^k)\). #include <bits/stdc++.h> #define FOR(i,a,b) for (int i=a; ...

  10. NOIP赛前集训营-提高组(第一场)#B 数数字

    题目描述 小N对于数字的大小一直都有两种看法.第一种看法是,使用字典序的大小(也就是我们常用的判断数字大小的方法,假如比较的数字长度不同,则在较短一个前面补齐前导0,再比较字典序),比如43<3 ...