做日志分析工作的经常需要跟成千上万的日志条目打交道,为了在庞大的数据量中找到特定模式的数据,常常需要编写很多复杂的正则表达式。例如枚举出日志文件中不包含某个特定字符串的条目,找出不以某个特定字符串打头的条目,等等。
使用否定式前瞻
正则表达式中有前瞻(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!
今天为网站伪静态写一条规则,目的是过滤除了站点本身以外的域名地址。由于网站做了泛域名解析,所以输入IP地址,或者其它人把域名绑定到服务器的
IP,都可以访问网站,今天就发现了一个域名,估计是好久没有用到了,一直就是解析这个IP,于是输入域名就到了网站,解决的方法就是在伪静态规则中把“
除了网站域名以外的其它域名均过滤掉”。
先写出“本站允许的所有域名”吧,用正则表达式,只要包含主要的域名就行了。前面可以是二级子域名,于是写成:
\w+\.k8008\.com\.cn
后缀扩展一下,就成下面这样,允许有多个后缀,这样可以是.com或者.net,.com.cn之类的了
\w+\.k8008(\.\w+)+
然后来转换成不含"k8008"的,这要用到正向预查了,"?="表示等于,“?!”表示不等于;要特别注意的是,预查后的位置,还是停留在预查之前,而不是从查完的字符开始找:
\w+\.(?!k8008)(\.\w+)+
上面这个在查完k8008后,位置是停留在“(?!”之前的“\.”,再接着找的是(?!k8008)后面的“\.”,其实并没有哪个域名会两个点号相连的,所以出错,得不到任何结果。于是在重读正则手册N+1次后,终于写了下面这句:
\w+(?!\.k8008)(\.\w+)+
非常简单,只需要把"\."移到预查里面就行了,最后加上边界条件,得到最终结果:
^\w+(?!\.k8008)(\.\w+)+$
我曾经的需求和上面的类似,网站也是需要支持泛解析的,同时把不是本站.xxx.com结尾的过滤掉。
正则表达式是:^(?!.*?\.xxx\.com).*$
我们网站支持下面格式的:abc.xxx.com,abc.xxx.com.cn,www.abc.xxx.com等形式
分享到:
相关推荐
例如,“正则表达式查找”命令可以找到字符串中所有匹配的子串,“正则表达式替换”则可以将匹配的子串替换成新的内容。 在编程实践中,我们可能会遇到一些挑战,如性能优化、错误处理等。例如,如果待处理的字符串...
在压缩包中的"PbRegeXP"文件可能是作者提供的一个示例代码或库,包含了实现正则表达式的类、函数或其他组件。通过研究这个文件,开发者可以了解如何在PowerBuilder 11.5中构建自己的正则表达式解决方案。 在Power...
2. **查找**:在字符串中查找符合正则表达式的部分。 3. **替换**:用新的字符串替换匹配到的正则表达式部分。 4. **分割**:根据正则表达式将字符串分割成多个子串。 5. **捕获组**:提取匹配的子串,特别是对于...
正则表达式(Deelx版)是一种强大的文本处理工具,它允许程序员和用户通过预定义的模式来匹配、查找、替换或者分析字符串。Deelx版是专门为提高正则表达式性能和功能而设计的一个支持库,适用于各种编程语言和应用场景...
在探讨如何利用正则表达式来判断一个字符串除指定字符外不包含其他特殊字符之前,我们首先需要了解正则表达式的基本概念以及本场景中的具体需求。 ### 正则表达式简介 正则表达式是一种强大的文本处理工具,能够...
本项目提供了一个C#编写的正则表达式测试工具,包含完整的源代码,可以帮助开发者调试和测试他们的正则表达式,支持查找和替换功能,并能直观地显示匹配结果。 1. **C#中的正则表达式基础** - `System.Text....
在Qt框架中,正则表达式(Regular Expression)是一种强大的文本处理工具,它允许程序员以结构化的方式匹配、查找、替换或验证字符串。本项目针对Qt的lineEdit组件,通过正则表达式实现了输入限制功能,使得lineEdit...
正则式,全称为“正则表达式”,是编程领域中一种强大的文本处理工具,用于匹配、查找、替换和分析字符串。它通过一系列特定的字符和语法构建模式,可以高效地处理各种复杂的文本匹配任务。在软件开发、数据处理、...
正则表达式的关键特性包括但不限于: - **特殊字符**:如`^`、`$`、`.`、`*`等,它们具有特殊的匹配意义。 - **字符集**:如`[abc]`表示匹配“a”、“b”或“c”中的任意一个字符。 - **重复量词**:如`*`表示匹配...
在易语言中,正则表达式类是一个非常重要的工具,用于处理字符串的模式匹配和查找。在处理中文文本时,这个功能尤为关键,因为中文字符的编码和处理方式与英文有所不同。 正则表达式是用于匹配字符串模式的一种强大...
- **JavaScript中的正则表达式**:JavaScript的正则表达式对象提供了丰富的功能,包括全局匹配、忽略大小写等选项。 - **.NET框架中的正则表达式**:通过System.Text.RegularExpressions命名空间提供支持。 #### 六...
正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和分析字符串。它通过预定义的模式来识别和操作字符串中的数据。以下是一些常见的正则表达式及其用途: 1. 匹配中文字符:`[u4e00-u9fa5]` - 这个正则...
在编程世界中,正则表达式(Regular Expression)是一种强大的文本处理工具,能够帮助开发者高效地进行字符串的匹配、查找、替换等操作。在Delphi 2010这个经典的集成开发环境中,有一款专门针对正则表达式的插件,...
2. **正则表达式(regex)在Lucene中的应用** 3. **regexQuery详解** 4. **示例代码解析** 5. **索引创建与查询流程** 6. **正则表达式的语法** #### Lucene简介 Lucene是一个高性能、全功能的全文搜索引擎库。它为...
8. Unicode汉字范围:`/^[u4e00-u9fa5],{0,}$/` 和匹配中文字符的正则表达式:`[\u4e00-\u9fa5]` - 这两个正则表达式用于检测字符串中是否包含中文字符。 9. 匹配双字节字符:`[^\x00-\xff]` - 用于识别多字节字符...
首先,文章强调了正则表达式与Windows/Dos下的文件查找通配符(如*和?)的区别,虽然类似,但正则表达式功能更加强大。正则表达式不仅可以匹配特定字符,还能进行位置匹配,以及限定字符出现的次数。正则表达式中的...
Java正则表达式是Java编程语言中用于处理字符串的强大工具,它基于模式匹配的概念,能够高效地进行文本搜索、替换和解析。在Java中,正则表达式主要通过`java.util.regex`包来实现,提供了Pattern和Matcher两个核心...
反义是指在正则表达式中,某些模式可以被否定,以便它们不能被匹配。例如,查找所有不包含a的字符串,可以使用[^a]来描述这种规则。 分组是指在正则表达式中,某些模式可以被分组,以便它们可以被匹配。例如,查找...
在Java中,正则表达式的语法相当丰富,包括但不限于: 1. 字符集:`[]`用来定义一组字符,比如`[abc]`表示匹配'a'、'b'或'c'。 2. 量词:`*`表示前面的字符可以出现零次或多次,`+`表示至少一次,`?`表示零次或一次...
正则表达式可以用于多种用途,包括但不限于: 1. **数据验证**:例如,验证邮箱地址、电话号码或网址格式是否正确。 2. **文本搜索**:快速查找文档或代码中包含特定模式的字符串。 3. **文本替换**:批量修改文件...