正则表达式之前瞻后顾,贪婪 与非贪婪

一、 前瞻后顾

1. 含义

表达式 含义 常用实例
非捕获组 (?:pattern) 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如"industr(?:y|ies)"就是一个比“industry|industries" 更简洁的表达式
前瞻 肯定式向前查找 (?=pattern) 正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,"Windows(?=95|98|NT|200)"能匹配"Windows2000”中的“Windows",但不能匹配"Windows3.1" 中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
负前瞻 否定式向前查找 (?!pattern) 正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)"能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows” ^(?!str)不以某字符串开头
/^(?!test).*/
后顾 肯定式向后查找 (?<=pattern) 反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows"能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”
负后顾 否定式向后查找 (?<!pattern) 反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。 (?<!str)$ 不以某字符串结尾 /.*(?<!end)$/

2. ?: 与?= 区别

  1. 共同点

    (?:pattern)(?=pattern)都匹配pattern,但不会把pattern结果放到Matches的集合中

  2. 区别

    • (?:pattern) 匹配得到的结果包含pattern,(?=pattern) 则不包含。如:

      \\ 对于字符串 " industry abc"
      industr(?:y|ies) => industry
      industr(?=y|ies) => industr

      const str = "industry abc"
      const reg = /industr(?:y|ies)/
      const reg1 = /industr(?=y|ies)/
      
      console.log(str.match(reg))
      console.log(str.match(reg1))
      
匹配结果.png
  • 是否消耗字符

    (?:pattern) 消耗字符,下一字符匹配会从已匹配后的位置开始。
    (?=pattern) 不消耗字符,下一字符匹配会从预查之前的位置开始。
    即后者只预查,不移动匹配指针。如:

匹配过程.png

3. 常用例子

正则表达式 含义
(?<=").*?(?=") 匹配引号中间的值

二、贪婪模式与非贪婪模式

含义

  • 贪婪与非贪婪模式影响的是\color{red}{被量词修饰的子表达式}的匹配行为.
  • 贪婪模式在\color{red}{整个表达式匹配成功}的前提下,尽可能\color{red}{多}的匹配.
  • 而非贪婪模式在\color{red}{整个表达式匹配成功}的前提下,尽可能\color{red}{少}的匹配.
贪婪模式量词 非贪婪模式量词(懒惰模式或惰性模式)
{m,n} {m,n}?
{m,} {m,}?
? ??
* *?
+ +?

示例

源字符串 正则表达式 匹配结果
aa<div>test1</div>bb<div>test2</div>cc <div>.*</div> <div>test1</div>bb<div>test2</div>
<div>.*?</div> <div>test1</div>
<div>.*</div>bb <div>test1</div>bb
<div>.*?</div>cc <div>test1</div>bb<div>test2</div>cc

三、参考

正则表达式-- (?:pattern)与(?=pattern)的区别
正则基础之——NFA引擎匹配原理
正则表达式 - 字符匹配不以某字段开头或者结尾
正则基础之——贪婪与非贪婪模式
深入理解正则表达式环视的概念与用法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容