• Java 正则?:?=?!的理解


      上图是官方文档的介绍,总结一下讲了两个知识点 ①是否获取匹配并保存匹配的值、②正向预查和反向预查。

    1:解释是否获取匹配并保存匹配的值

    1. ()表示捕获分组,获取匹配,()把每个分组里的匹配的值保存起来
    2. (?:)表示非捕获分组,获取匹配,非捕获分组匹配的值不会保存起来,可以提高程序执行速度
    3. (?=?!?<=?<!)表示非捕获分组,不获取匹配,也不保存匹配的值

    举例说明:

    // 是否获取匹配
    测试文本 abxoxcd
    ..(xox).. 匹配 abxoxcd
    ..(
    ?:xox).. 匹配 abxoxcd ..(?=xox).. 匹配 abxo

    获取匹配,一般匹配到了字符之后,该字符就被消耗、输出。不获取匹配,不会消耗字符。

    // 是否保存匹配的值 测试文本 AAABBCaaA E666FF (A)\1* 匹配 AAA、A (\w)\1+ 匹配 AAA、BB、aa、666、FF (?:A)(B)\1* 匹配 ABB

    因为非捕获分组不保存匹配的值,所以  (?:A)(B)\1* 匹配 ABB 第一个\1表示(B)这个捕获组捕获到的值。  “注意:反向引用表示捕获到的值,而不是再次使用正则表达式”

    这里用到了一个新的知识点,反向引用。
      

      1、正则表达式中  “ umber” 表示反向引用,表示引用一个捕获组,需要和小括号 “()” 一起使用

      2、正则捕获组的下标从 0 开始,下标为 0 的组是整个表达式,下标为 1 的表示从左到右开始的第一个左括号所包含的值,后面的数字以此类推

      3、捕获组在匹配成功时,会将子表达式匹配到的内容,保存到内存中一个以数字编号的组里,可以简单的认为是对一个局部变量进行了赋值,这时就可以通过反向引用的方式,引用这个局部变量的值。

      4、反向引用必须要与捕获组一同使用,如果没有捕获组,而使用了反向引用的语法,不同语言的处理方式不一致,有的语言会抛异常,有的语言会当作普通的转义处理

    2:解释正向预查和反向预查

    // 前瞻:
    exp1(?=exp2)   查找exp2前面的exp1
    // 后顾:
    (?<=exp2)exp1  查找exp2后面的exp1
    // 负前瞻:
    exp1(?!exp2)   查找后面不是exp2的exp1
    // 负后顾:
    (?<!exp2)exp1  查找前面不是exp2的exp1

    举例说明:

    // 正向预查和反向预查
    测试文本 abxoxcd
    
      ..(?=xox)  匹配 ab
    
      ..(?=oxo)  匹配不到

    (?=xox).. 匹配xo (
    ?<=xox).. 匹配 cd

    预查只需要记住:1、环顾全局定位到非捕获组;2、不获取匹配(不消耗字符),不保存匹配的值(不能使用反向引用)

    加餐

    提问:强密码(必须包含数字、小写字母和大写字母三种字符,即这三种字符的组合,且不能使用特殊字符,长度在8-16之间),你认为必须是 1个数字+1个小写字母+1个大写字母 这种顺序吗?

     ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,16}$ 

    (?=.*[0-9])表示任意字符+一个数字

    (?=.*[a-z])表示任意字符+一个小写字母

      (?=.*[A-Z])表示任意字符+一个大写字母

      [0-9a-zA-Z]{8,16}表示8-16个数字、大小写字母

    当有多个正向预查规则时它们是并列的,不是串行的

    举例说明:

    测试文本 abc2abc
    
      \d(?=a)(?=b)  匹配不到
    
      \d(?=a)(?=.b) 匹配 2   当然这是为了演示它的规则,其实可以写 \d(?=ab)

    这里主要的原因是:不获取匹配(不消耗字符)。

    对于 ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,16}$ 
    其实整个正则表示可以分为三部分:
    /^(?=.*[0-9])[0-9a-zA-Z]{8,16}$/
    /^(?=.*[a-z])[0-9a-zA-Z]{8,16}$/
    /^(?=.*[A-Z])[0-9a-zA-Z]{8,16}$/
    待匹配字符串必须同时满足这三部分才可以


    【参考】

    1. https://www.jianshu.com/p/9c4979a3b7e4
    2. http://www.45fan.com/article.php?aid=19101105382209663550874595
    3. https://www.runoob.com/java/java-regular-expressions.html
    4. https://www.runoob.com/regexp/regexp-syntax.html
    5. https://www.cnblogs.com/archermeng/p/7537244.html
     
    本文作学习交流用,如有错误,欢迎指正!
  • 相关阅读:
    lua 计算字符串字符个数“中文字算一个字符”
    C API
    词汇
    LUA 创建文件和文件夹
    lua lfs库
    Unity3d gameObject
    Unity3d Time
    Unity3d Vector3
    Unity3d transform
    从Oracle数据库中的本地命名文件tnsnames.ora来看服务别名、服务名和实例名的区别。
  • 原文地址:https://www.cnblogs.com/pan1042/p/12121382.html
Copyright © 2020-2023  润新知