IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

日志扫描之利器:否定式前瞻的正则表达式

淘宝数据平台团队 2010-05-24 16:27:14 累计浏览 3,429 次
本机暂存

数据平台的源数据,很大部分来源于日志。一说到日志扫描和解析,不可避免就涉及到正则表达式匹配,没有了正则表达式,日志的匹配就很难做到自动化和高效。

在日志匹配中,有种常见的匹配情形,叫“不包含”。就是说,我们希望这条日志,在匹配某个通用特征的情况下,又不包含某个特征,例如说:

A pig is running.

我们希望匹配到所有带pig的日志,但是我们不希望匹配到pig带running的日志。而且我们不希望改程序,扫描或者解析2次,我们希望一次匹配就能匹配出,带pig而不带running的日志。

这种情况,貌似需要编程解决,但是强大而无所不能的正则表达式,早就考虑到了这种情况,并且优雅的解决了。这个正则表达式技术,就叫:

否定式前瞻

具体的否定式前瞻的解释,可以看看这篇图文并茂的文章,我相信没有那篇文章比它解释得更加通俗易懂了。

http://www.it118.org/Specials/61f53524-21fe-4ad9-a62b-0b6e515deaf9/412e8b3f-6008-4e4d-99d0-d2ac14f344f8.htm

我要在这里强调的只是两点:

1. 上面的文章,给出的正则表达式语法不是Java的,所以你照样copy的话,到了Java是不生效的。这里我翻译一下,给出Java个版本的否定式前瞻正则表达式,注意它同样适用于Python。

匹配淘宝item的url,但是不带ali_trackid

http://item.taobao.com/item.htm\?id=[0-9](?!.*ali_trackid).*

2. 这个表达式,重点是括号里面的(.*)和括号外面的.*。不能够写成 .*(?!.*ali_trackid).*。具体原因,参考文章中有详细的说明。

最后,补补正则表达式中,非捕获组的基本概念。

最后解释一下非捕获组的语法。我们都知道,Java和Python中,()表示捕获组,但是一旦是(?),就表示非捕获组了。具体解释可以看:

http://www.blogjava.net/sdyjmc/archive/2010/01/06/308391.html

前对应右,后对应坐,前瞻后顾,正则表达式之美也~~~其中,否定式前瞻的应用最为实用,日志扫描中,经常会用到,请细心体会研究。

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. vim几个小技巧(批量替换,列编辑) (累计阅读 37,516)
  2. AWK介绍 (累计阅读 6,709)
  3. 正则表达式基础 (累计阅读 6,316)
  4. Perl命令行常见用法及技巧 (累计阅读 5,912)
  5. 正则表达式的与或非 (累计阅读 5,870)
  6. 百度搜索URL参数解析 (累计阅读 5,719)
  7. VIM查找替换归纳总结 (累计阅读 5,389)
  8. 操作大文本,awk vs vim (累计阅读 5,095)
  9. PHP 正则里面的两个重要技巧 (累计阅读 4,371)
  10. bash shell - sed, awk文本捕获及替换 (累计阅读 4,274)