博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)使用零宽断言来匹配不包含连续字符串的行
阅读量:5243 次
发布时间:2019-06-14

本文共 1485 字,大约阅读时间需要 4 分钟。

原文地址:

最近在工作中遇到一个问题,有 N 个字符串,需要用正则表达式去过滤掉不包含某一个特定连续字符串(比如abc)的字符串。

在网上搜罗了一大把,找到了在 Perl 5 的正则表达式中有零宽断言这个东西,非常强大,先来了解下零宽断言倒是是什么?

简单的说,零宽断言是查找在某些内容之前或者之后的东西,这样解释起来可能比较抽象,我们来具体看下几种零宽断言:

  • (?=exp):这个零宽断言用来断言自身出现的位置之后能够匹配到表达式 exp,考虑下面这一个正则表达式 q(?=u),这个正则表达式表示匹配后面的字符是 u 的 q
  • (?!exp):这个零宽断言用来断言自身出现的位置之后不能够匹配到表达式 exp,看下面这一个正则表达式 q(?!u),这个正则表达式表示匹配后面的字符不是 u 的 q
  • (?<=exp):这个零宽断言用来断言自身出现的位置之前能够匹配到表达式 exp
  • (?<!exp):这个零宽断言用来断言自身出现的位置之前不能够匹配到表达式 exp

在理解零宽断言的时候需要注意的一点是它是一种断言,也就是说零宽断言只会告诉你匹不匹配,但是不会“消费”掉字符串内的内容,我用下面的这一个例子来解释这个情况:

我们有一个正则表达式 k(?=h)otyn,用它去匹配 khotyn,乍看一下这个匹配是会成功的,但是由于零宽断言只做断言,而不会”消费“掉匹配到的字符串,所以事实上,这个正则表达式匹配是一个后面是 h 的 k,并且这个 k 的后面是 otyn,这样这个正则表达式无论什么字符串都会匹配失败(正确的应该是 k(?=h)hotyn,不过这样加不加零宽断言并没有意义)。

在理解零宽断言以后,我们来看一下如何来匹配出不包含“abc”的字符串,下面是我写出的结果:

1
((?!abc).)+

首先我们看这个正则表达式里面的 (?!abc). 部分,这个部分断言一个空字符后面不能够匹配到字符串abc,并且这个空字符串后面是一个任意字符。

我们来看下下面这一段代码:

1234
Pattern pattern = new Perl5Compiler().compile("((?!abc).)+");Perl5Matcher matcher = new Perl5Matcher();System.out.println(matcher.matches("abc", pattern));System.out.println(matcher.matches("abdas dfas", pattern));

这段代码的执行结果是:

12
falsetrue

第一个匹配失败是因为在字符 ‘a’ 前面的空字符后面匹配到了字符串 “abc”,因此断言失败,从而匹配失败。

第二个匹配成功是因为没有任何一个空字符后面有出现 “abc” ,因为匹配成功。

最后加上 + 号的原因是因为能够做到完全匹配,因为任何一个字符只要其本身不是 ‘a’,并且后面不是 ‘bc’,那么就是能够匹配 “(?!abc).” 的,因此,只要一个字符串里面不包含 abc,那么它就能够完全匹配 ((?abc).)+

PS:这片文章其实是前几年写的,之前的博客被关闭了,数据丢了,幸好当时在 Iteye 上还有一份,于是就迁移过来。这几年我经常用这个方式来分析线上服务器的日志,可以说,有了零宽断言,省去了非常多的麻烦~,定位问题的速度也快了不少,零宽断言的确是一个非常犀利的东西。

转载于:https://www.cnblogs.com/fcsh820/p/3479489.html

你可能感兴趣的文章
Eclipse 安装插件
查看>>
国外常见互联网盈利创新模式
查看>>
Oracle-05
查看>>
servlet-01
查看>>
伊人笑 2010年
查看>>
[Papers]MHD, $\p_3\pi$, Lebesgue space [Jia-Zhou, JMAA, 2012]
查看>>
《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(下)
查看>>
AtCoder Beginner Contest 100 C(思维)
查看>>
最大流算法
查看>>
wifi 攻破
查看>>
如何使用好android的可访问性服务(Accessibility Services)
查看>>
Python测试字符串是否为数字
查看>>
拓扑排序
查看>>
Open Associated Perspective?
查看>>
oracle字符集设置
查看>>
Java页面中文编码要转换两次encodeURI
查看>>
C# Image和Byte[]互相转换
查看>>
Jmeter组件认识
查看>>
C#反射(转载)
查看>>
SQL 课程
查看>>