利⽤正则表达式排除特定字符串
查不以baidu开头的字符串
baidu
sina
正则:^(?!baidu).*$  匹配结果就是第2⾏,也就是第1⾏被排除了
这⾥使⽤了零宽度断⾔(?!exp),注意,我们有⼀个向前查的语法(也叫顺序环视)  (?=exp)
(?=exp) 会查exp之前的【位置】如果将等号换成感叹号,就变成了否定语义,也就是说查的位置的后⾯不能是exp
⼀般情况下?!要与特定的锚点相结合,例如^⾏开头或者$⾏结尾,那么上⾯的例⼦的意思如下:
^(?!baidu).*$ 先匹配⼀个⾏开头的位置,并且要求接下来的位置的后⾯不是baidu这个字符串。这样由于第⼀⾏^之后的位置后⾯是baidu所以匹配失败,被排除在外了。
查不以com结尾的字符串
www.sina
www.baidu
www.123
正则 ^.*?(?<!com)$  匹配前3⾏结果。
如果查以com结尾的字符串则使⽤正则 ^.*?(?<=com)$或者 ^.*?com$
对正则表达式的解释:^.*?(?<!com)$
⾸先匹配⾏开头,然后是 .*? 这个是忽略优先,也就是优先忽略不匹配任何字符,(?<!com) 这个是⼀个逆序环视的否定形式,意思是匹配⼀个位置此位置的前⾯不能是字符串com,最后是⼀个⾏结束。对于www.123来说,⾸先匹配⾏⾸,接着匹配w后⾯的位置,发现前⾯不是com,所以成功但紧接着要匹配⾏尾,失败,回溯让.*? 匹配⼀个w符号,接着(?<com)匹配第⼆个w后⾯的位置,发现前⾯也不是com匹配成功,紧接着要匹配$对应的⾏尾失败,⼀直到.*?匹配了www.baidu的时候,此时(?<!com)匹配m后⾯的位置,此时此位置的前⾯是com匹配直接失败,接着.*?匹配⾏末尾,(?<!com)匹配$后⾯的位置,显然这次也失败了,所以整个全局匹配都失败。  www.123被排除到匹配之外。这⾥的.*后⾯加不加问号结果都⼀样。
查不含有if的⾏
if (a>b)
printf("hello");
else if(a<b)
printf("hello2");
else
printf("hello3");
正则 ^([^f]|[^i]f)+$
其实这个匹配也是⼀个排除型字符串的匹配,但是不同于上⾯两种,因为这⾥的if可能既不在⾏开头,也不在⾏结尾,⽽是在字符串中间这样就给匹配带来了⿇烦,在正则表达式中没有提供类似排除的功能。我们最容易想到的就是下⾯的正则:
^[^if]+$ 这种写法看起来是那么回事,但是排除型字符组排除的是i和f两个字符,⽽不是if这个字符串,所以这个正则表达
式匹配的是那些既没有i字符也不包含f字符的字符串。但是如果字符串中有⼀个i或多个i或者有⼀个或多个f,或者i和f字符都有只不过没有连在⼀起。这些情况都是我们需要匹配的情况,⽽我们不能匹配的情况是那些包含if字符串的⾏,⽽不是包含i或f字符的⾏,所以这种写法漏洞很⼤。
^.*(?!if).*$ 这种写法使⽤了零宽度断⾔,表⾯意思看起来好像是说任意字符+⾮if+任意字符组成了整个字符串,但是仔细研究匹配过程就知道这个是错的,(?!if)匹配的是⼀个位置,所以对于字符串aifb他也是可以匹配到的,⽽实际上这样的字符正是我们不要的。按照这个正则表达式,对于aifb ⾸先匹配⾏⾸,其次.*是贪婪模式(匹配优先),会⼀直匹配到字符串的末尾(此时传动装置定位在$位置前⾯),此时(?!if)需要匹配⼀个位置,这个位置的后⾯不能是if,这个时候正好位置在b字符的后⾯,符合匹配条件,紧接着匹配⾏尾,到这⾥整个全局匹配成功。
也就是说对于⼀个字符串例如我要排除abc这个字串,那么对于任意⼀个字符串  helloworld abc helloworld 在匹配的时候(?!abc)可以匹配h、e、l、l、o、w、o、r、l、d等这些字符后⾯的位置,都是成功的。所以匹配根本还没有进⾏到abc这个地⽅,(?!abc)就会匹配成功。这个时候根本起不到排除的作⽤,为什么上⾯的第1和第2个例⼦可以呢,因为他们的位置有⾏⾸和⾏尾限定。例如我要匹配⾏⾸不是abc的话,那么此时^(?!abc) 这个时候(?!abc)实际上在匹配的时候其传动装置的位置被⾏⾸进⾏了限定,所以对于那些以abc开头的字符串来说就会匹配失败了。
对于正则表达式^.*(?!abc).*$怎么能让第⼀个.*匹配到 helloworldabcxxx中的helloworld的问题。
对于上⾯的题⽬,我们的答案是^([^f]|[^i]f)+$  其实就将所有的匹配分成了2种情况,⼀种情况是假设字符串中没有f字符,
⾃然就不可能有if字符串了,这种情况下正则匹配特定字符串
匹配的字符串中是不可能有if的。第⼆种情况就是有f字符,但是我们要求此时f的前⾯不能是i,所以在有f和没有f两种情况都考虑到的情况下,这个正则就应该可以满⾜所有的情况了。
其实这个问题的解答是不完美的,对于排除的字符串if只有2个字符i和f字符,我们可以使⽤这种⽅式,但是如果我们要排除的是字符串helloworld,这种⽅法显然就不实⽤了,那要考虑到多少种情况呢?
排除不含有某字符串的最终⽅案:在这种情况下我们使⽤  ^(?!.*helloworld).*$  正则表达式我们将第⼀个.*移到了零宽度断⾔的⾥⾯。在匹配的时候⾸先匹配⾏⾸的位置,然后接下来是匹配⾏⾸后⾯的位置,要求此位置的后⾯不能是    .*helloworld 匹配的字符串,说⽩了要求此位置的后⾯不能是xxxxxxxxxxxxxxxxxxhelloworld 类似的字符串,这样就排除了从⾏⾸开始后⾯含有helloworld的情况了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。