正则表达式——2.前瞻断言与后瞻断言(java正则表达式校验密码必须是包含大小写字母、数字、特殊符号的8位以上组合))
创始人
2024-05-26 14:56:29
0

文章目录

  • 1.概述
  • 2.前瞻断言
  • 3.否定的前瞻断言
  • 4.后瞻断言
  • 5. 捕获组
  • 6.在密码强度规则中的应用
  • 7.总结

1.概述

正则表达式之前瞻断言与后瞻断言
有时我们只需要为一个模式找到那些在另一个模式之后或之前的匹配项。
有一种特殊的语法,称为“前瞻断言(lookahead)”和“后瞻断言(lookbehind)”。
首先,让我们从字符串中查找价格,例如 1 turkey costs 30€。即:一个数字,后跟€符号。

2.前瞻断言

语法为:x(?=y),它表示“仅在后面是 Y 时匹配 X”。这里的 X 和 Y 可以是任何模式。

那么对于一个后面跟着 € 的整数,正则表达式应该为:\d+(?=€)。

let str = "1 turkey costs 30€"; alert( str.match(/\d+(?=€)/) ); //
30,数字 1 被忽略了,因为它后面没有 €

请注意:前瞻断言只是一个测试,括号 (?=…) 中的内容不包含在匹配结果 30 中。

当我们查找 X(?=Y) 时,正则表达式引擎会找到 X,然后检查其后是否有 Y。如果没有,则跳过潜在匹配,并继续搜索。

更复杂的测试也是可能的,例如 X(?=Y)(?=Z) 表示:

寻找 X。
检查 Y 是否紧跟在 X 之后(如果不是则跳过)。
检查 Z 是否也在 X 之后(如果不是则跳过)。
如果两个测试都通过了,那么 X 是匹配的,否则继续搜索。
换句话说,这样的模式意味着我们同时在寻找 X 后跟 Y 和 Z。

这只有在模式 Y 和 Z 不是互斥的情况下才可行。

例如,\d+(?=\s)(?=.*30) 查找后跟着空格 (?=\s) 的 \d+,并且有 30 在它之后的某个地方 (?=.*30):

let str = "1 turkey costs 30€";
alert( str.match(/\d+(?=\s)(?=.*30)/) ); // 1

在我们给出的字符串中,与数字 1 完全匹配。

3.否定的前瞻断言

假设我们想要一个数量,而不是来自同一字符串的价格。那是一个数字 \d+,后面不是 €。

为此,我们可以使用否定的前瞻断言。

语法是:X(?!Y),意思是“搜索 X,但前提是后面没有 Y”。

let str = "2 turkeys cost 60€";
alert( str.match(/\d+\b(?!€)/g) ); // 2(价格不匹配)

4.后瞻断言

⚠️ 后瞻断言的浏览器兼容情况
请注意:非 V8 引擎的浏览器不支持后瞻断言,例如 Safari、Internet Explorer。
前瞻断言允许添加一个“后面要跟着什么”的条件判断。

后瞻断言也类似,只不过它是在相反的方向上进行条件判断。也就是说,它只允许匹配前面有特定字符串的模式。

语法为如下:

  • 肯定的后瞻断言:(?<=Y)X,匹配 X,仅在前面是 Y 的情况下。
  • 否定的后瞻断言:(? 例如,让我们把价格换成美元。美元符号通常在数字前面,所以要查找 $30 我们将使用 (?<=$)\d+ —— 一个前面带 $ 的数值:
let str = "1 turkey costs $30";
// 美元符号被转义 \$
alert( str.match(/(?<=\$)\d+/) ); // 30(跳过了仅仅是数字的值)

如果我们需要找到量词 —— 一个前面不带 $ 的数字,我们可以使用否定的后瞻断言:(?

let str = "2 turkeys cost $60";
alert( str.match(/(?

5. 捕获组

一般来说,前瞻断言和后瞻断言括号中的内容不会成为结果的一部分。

例如,在模式 \d+(?!€) 中,€ 符号就不会出现在匹配结果中。这是很自然的事:我们寻找一个数字 \d+,而 (?=€) 只是一个测试,表示要匹配的数字后面应该紧跟着 € 字符。

但在某些情况下,我们可能还想捕获前瞻断言和后瞻断言所匹配的内容,或者部分内容。这也是可行的。只需要将该部分包装在额外的括号中。

在下面的示例中,货币符号 (€|kr) 和金额一起被捕获了:

let str = "1 turkey costs 30€";
let regexp = /\d+(?=(€|kr))/; // €|kr 两侧有额外的括号
alert( str.match(regexp) ); // 30, €

后瞻断言也一样:

let str = "1 turkey costs $30";
let regexp = /(?<=(\$|£))\d+/;
alert( str.match(regexp) ); // 30, $

6.在密码强度规则中的应用

java正则表达式校验密码必须是包含大小写字母、数字、特殊符号的8位以上组合
一、需求:密码必须是包含大写字母、小写字母、数字、特殊符号(不是字母,数字,下划线,汉字的字符)的8位以上组合

二、方案:利用正则表达式来校验

三、思路:排除法

1、排除大写字母、小写字母、数字、特殊符号中1种组合、2种组合、3种组合,那么就只剩下4种都包含的组合了

2、表达式为:^(?![A-Za-z0-9]+$)(?![a-z0-9\\W]+$)(?![A-Za-z\\W]+$)(?![A-Z0-9\\W]+$)[a-zA-Z0-9\\W]{8,}$

3、拆分解释:其中(2)-(6)运用了零宽断言、环视等正则功能

(1)^匹配开头

(2)(?![A-Za-z0-9]+$)匹配后面不全是(大写字母或小写字母或数字)的位置,排除了(大写字母、小写字母、数字)的1种2种3种组合

(3)(?![a-z0-9\W]+$)同理,排除了(小写字母、数字、特殊符号)的1种2种3种组合

(4)(?![A-Za-z\W]+$)同理,排除了(大写字母、小写字母、特殊符号)的1种2种3种组合

(5)(?![A-Z0-9\W]+$)同理,排除了(大写字母、数组、特殊符号)的1种2种3种组合

(6)[a-zA-Z0-9\W]匹配(小写字母或大写字母或数字或特殊符号)因为排除了上面的组合,所以就只剩下了4种都包含的组合了

(7){8,}8位以上

(8)$匹配字符串结尾

四、代码:

public class RegexTest {public static final String PW_PATTERN = "^(?![A-Za-z0-9]+$)(?![a-z0-9\\W]+$)(?![A-Za-z\\W]+$)(?![A-Z0-9\\W]+$)[a-zA-Z0-9\\W]{8,}$";public static void main(String[] args) {String pw1 = "ABCDEFGHIG";String pw2 = "abcdefghig";String pw3 = "0123456789";String pw4 = "!@#$%^&*()";String pw5 = "ABCDEabcde";String pw6 = "ABCDE01234";String pw7 = "ABCDE!@#$%";String pw8 = "abcde01234";String pw9 = "abcde!@#$%";String pw10 = "01234!@#$%";String pw11 = "abcde01234!@#$%";String pw12 = "ABCDE01234!@#$%";String pw13 = "ABCDEabcde!@#$%";String pw14 = "ABCDEabcde01234";String pw15 = "Aa0!";//符合要求密码String pw16="ABCabc012!@#";System.out.println(pw1.matches(PW_PATTERN));System.out.println(pw2.matches(PW_PATTERN));System.out.println(pw3.matches(PW_PATTERN));System.out.println(pw4.matches(PW_PATTERN));System.out.println(pw5.matches(PW_PATTERN));System.out.println(pw6.matches(PW_PATTERN));System.out.println(pw7.matches(PW_PATTERN));System.out.println(pw8.matches(PW_PATTERN));System.out.println(pw9.matches(PW_PATTERN));System.out.println(pw10.matches(PW_PATTERN));System.out.println(pw11.matches(PW_PATTERN));System.out.println(pw12.matches(PW_PATTERN));System.out.println(pw13.matches(PW_PATTERN));System.out.println(pw14.matches(PW_PATTERN));System.out.println(pw15.matches(PW_PATTERN));System.out.println(pw16.matches(PW_PATTERN));}
}

输出结果除最后一行外全是false,即只有最后一个密码是符合要求的

7.总结

当我们想根据前面/后面的上下文匹配某些内容的时候,前瞻断言和后瞻断言(通常被称为“环视断言”)很有用。

对于简单的正则表达式,我们可以手动执行类似的操作。即:不管上下文,匹配所有可匹配的内容,然后在循环中根据上下文进行过滤。

请记住,str.match(没有修饰符 g)和 str.matchAll(总是)将匹配项作为具有 index 属性的数组返回,因此我们知道它在文本中的确切位置,并且可以检查上下文。

但通常环视断言更方便。

环视断言类型:

模式类型匹配
X(?=Y)肯定的前瞻断言X 后紧跟着 Y
X(?!Y)否定的前瞻断言X 后没紧跟着 Y
(?<=Y)X肯定的后瞻断言X 紧跟在 Y 后面
(?否定的后瞻断言X 没紧跟在 Y 后面

相关内容

热门资讯

emui 安卓系统对应关系,E... 你有没有发现,每次打开你的华为手机,那个界面看起来是不是特别顺眼?那是因为华为的EMUI系统,它就像...
永诺安卓系统相机,功能解析与使... 你有没有发现,手机拍照已经成为我们生活中不可或缺的一部分?而在这其中,永诺安卓系统的相机功能可是相当...
tinder安卓版系统错误,揭... 最近在使用Tinder安卓版的时候,你是不是也遇到了一些让人头疼的系统错误呢?别急,今天就来和你聊聊...
htc安卓系统怎么更新系统,轻... 亲爱的HTC安卓用户们,你是不是也和我一样,时不时地想给手机来个“大变身”,让它焕然一新呢?没错,今...
安卓最新发布系统,颠覆性更新与... 你知道吗?最近安卓系统又来了一次大变身,这可是科技圈里的大事哦!安卓最新发布的系统,简直就像是一个全...
华为不升级安卓系统,开启自主操... 你知道吗?最近有个大新闻在科技圈里炸开了锅,那就是华为决定不再升级安卓系统!这可不是一个小决定,它背...
安卓保护系统停止运行,紧急排查... 亲爱的手机用户们,你们有没有遇到过这样的情况:手机突然间变得不正常了,安卓保护系统竟然停止运行了?这...
安卓系统记录仪,智能行车安全守... 你有没有想过,开车的时候,那些瞬间发生的事情,就像电影里的精彩片段,一闪而过,却让人回味无穷?别急,...
安卓13系统怎样升级,全面解析... 你有没有发现,你的安卓手机最近是不是有点儿“蔫儿”了?别急,别急,我来告诉你怎么给它来个“大变身”—...
安卓手机进去系统花屏,安卓手机... 手机屏幕突然花屏了,是不是瞬间感觉整个世界都变得不美好了呢?别急,今天就来和你聊聊安卓手机进入系统时...
安卓手机 系统怎么更新,体验最... 亲爱的手机控们,你是不是也和我一样,时不时地想给安卓手机来个“美容”大变身呢?没错,说的就是系统更新...
妈妈手机推荐安卓系统,安卓系统... 亲爱的妈妈们,是不是在为给家里的宝贝挑选一款合适的手机而烦恼呢?别急,今天我就来给你详细介绍一下几款...
oppo安卓版系统设置,全面解... 亲爱的手机控们,你是不是也和我一样,对OPPO安卓版系统的设置充满了好奇?想要让你的OPPO手机更加...
安卓系统是什么cp,CP架构下... 你有没有想过,你的手机里那个默默无闻的安卓系统,其实就像是一个超级贴心的CP(情侣搭档)呢?没错,就...
系统垃圾清理大师 安卓,安卓手... 手机里的垃圾文件是不是让你头疼不已?别急,今天我要给你介绍一位安卓系统里的“清洁小能手”——系统垃圾...
安卓系统分为几层,安卓系统分层... 你知道吗?安卓系统,这个陪伴我们手机生活的“小助手”,其实它内部结构可是相当复杂的呢!今天,就让我带...
系统最像苹果的安卓,揭秘最像苹... 你有没有发现,现在的安卓手机越来越像苹果了?没错,就是那个以简洁设计和流畅体验著称的苹果。今天,就让...
安卓更新13系统游戏,性能升级... 你知道吗?最近安卓系统又来了一次大变身,那就是安卓13系统!这次更新可是带来了不少惊喜,尤其是对那些...
安卓系统开机出错了,安卓系统开... 手机突然开不了机了,这可怎么办?别急,让我来帮你分析一下安卓系统开机出错的那些事儿。一、安卓系统开机...
vovg是安卓系统吗,安卓系统... 你有没有听说过Vovg这个操作系统?最近,这个名词在数码圈里可是引起了不小的热议呢!很多人都在问,V...