正则表达式环视、断言、预查的位置?

正则表达式环视、断言、预查的位置?

在如下博文中:

利用正则表达式排除特定字符串

判断不以baidu开头的字符串,使用了 ^(?!baidu).*$ 这个正向否定预查

判断不已com结尾的字符串,使用了^.*?(?<!com)$ 这个反向否定预查

正向预查,通常应该放在匹配字符串的后面

反向预查,通常应该放在匹配字符串的前面

这里都反过来使用,既然,正向预查也能放在匹配串前面,那么反向预查的存在岂不没有意义了?


回答:

你没理解向前预查和向后预查的含义

^(?!baidu).*$^(?<!baidu).*$ 的意义是不一样的

^(?!baidu).*$ 是“一个后面不跟着 baidu 的开头(更准确是开头的空字符串)”+“一个任意字符串(不包含 \r\n)”+“一个结尾”
^(?<!baidu).*$ 是“一个开头”+“一个不在 baidu 后面的任意字符串”+“一个结尾”,这是没有意义的,因为字符串既然在开头,其之前就一定不是 baidu,所以这个表达式始终成立

要判断不以baidu开头,.*$ 可以去掉,然后使用部分匹配的函数来判断,以 js 为例:

/^(?!baidu)/.test('baidu.com'); // false, 因为没有“一个后面不跟着baidu的开头”

/^(?!baidu)/.test('www.baidu.com'); // true, 因为存在“一个后面不跟着baidu的开头”

/^(?<!baidu)/.test('baidu.com'); // true, 始终返回true, 因为存在“一个开头”+“一个不在baidu后面的空字符串”

// 看下面例子理解一下向前预查和向后预查的含义

/^www.(?=baidu).com$/.test('www.baidu.com'); // false

/^www.(?<=baidu).com$/.test('www.baidu.com'); // false

/^www.(?=baidu)baidu.com$/.test('www.baidu.com'); // true

/^www.(?<=baidu)baidu.com$/.test('www.baidu.com'); // false

/^www.baidu(?=baidu).com$/.test('www.baidu.com'); // false

/^www.baidu(?<=baidu).com$/.test('www.baidu.com'); // true


回答:

例子的问题吧。改成这样是不是就没有疑义了。
判断e结尾的单词,但是不包括life,使用了 ^(?!lif).*e$ 这个正向否定预查
判断a开头的单次,但是不包括apple使用了^a.*?(?<!pple)$ 这个反向否定预查

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。


回答:

正向预查确实可以放前面,但它不会检查表达式的后面,所以,放前面也没用。负向预查同理。这两种功能是不相同的,但他们确能同时表达同一个字符,但确是两个不同的角度。

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。


回答:

可能有多个方式构建完成类似任务的规则式,但不同方式的复杂程度不同,
这里不同的规则语法适用于在不同的场景来更方便的构建出合适的规则式。

就是完成同样的效果,可能利用规则1的语法比利用规则2的语法更简便,明确,这也是不同规则语法存在的价值。


已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。

以上是 正则表达式环视、断言、预查的位置? 的全部内容, 来源链接: utcz.com/p/938469.html

回到顶部