正则表达式——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 后面

相关内容

热门资讯

安卓子系统windows11,... 你知道吗?最近科技圈可是炸开了锅,因为安卓子系统在Windows 11上的兼容性成了大家热议的话题。...
电脑里怎么下载安卓系统,电脑端... 你有没有想过,你的电脑里也能装上安卓系统呢?没错,就是那个让你手机不离手的安卓!今天,就让我来带你一...
索尼相机魔改安卓系统,魔改系统... 你知道吗?最近在摄影圈里掀起了一股热潮,那就是索尼相机魔改安卓系统。这可不是一般的改装,而是让这些专...
安卓系统哪家的最流畅,安卓系统... 你有没有想过,为什么你的手机有时候像蜗牛一样慢吞吞的,而别人的手机却能像风一样快?这背后,其实就是安...
安卓最新系统4.42,深度解析... 你有没有发现,你的安卓手机最近是不是有点儿不一样了?没错,就是那个一直在默默更新的安卓最新系统4.4...
android和安卓什么系统最... 你有没有想过,你的安卓手机到底是用的是什么系统呢?是不是有时候觉得手机卡顿,运行缓慢,其实跟这个系统...
平板装安卓xp系统好,探索复古... 你有没有想过,把安卓系统装到平板上,再配上XP系统,这会是怎样一番景象呢?想象一边享受着安卓的便捷,...
投影仪装安卓系统,开启智能投影... 你有没有想过,家里的老式投影仪也能焕发第二春呢?没错,就是那个曾经陪你熬夜看电影的“老伙计”,现在它...
安卓系统无线车载carplay... 你有没有想过,开车的时候也能享受到苹果设备的便利呢?没错,就是那个让你在日常生活中离不开的iOS系统...
谷歌安卓8系统包,系统包解析与... 你有没有发现,手机更新换代的速度简直就像坐上了火箭呢?这不,最近谷歌又发布了安卓8系统包,听说这个新...
微软平板下软件安卓系统,开启全... 你有没有想过,在微软平板上也能畅享安卓系统的乐趣呢?没错,这就是今天我要跟你分享的神奇故事。想象你手...
coloros是基于安卓系统吗... 你有没有想过,手机里的那个色彩斑斓的界面,背后其实有着一个有趣的故事呢?没错,我要说的就是Color...
安卓神盾系统应用市场,一站式智... 你有没有发现,手机里的安卓神盾系统应用市场最近可是火得一塌糊涂啊!这不,我就来给你好好扒一扒,看看这...
黑莓平板安卓系统升级,解锁无限... 亲爱的读者们,你是否还记得那个曾经风靡一时的黑莓手机?那个标志性的全键盘,那个独特的黑莓体验,如今它...
安卓文件系统采用华为,探索高效... 你知道吗?最近安卓系统在文件管理上可是有了大动作呢!华为这个科技巨头,竟然悄悄地给安卓文件系统来了个...
深度系统能用安卓app,探索智... 你知道吗?现在科技的发展真是让人惊叹不已!今天,我要给你揭秘一个超级酷炫的话题——深度系统能用安卓a...
安卓系统的分区类型,深度解析存... 你有没有发现,你的安卓手机里藏着不少秘密?没错,就是那些神秘的分区类型。今天,就让我带你一探究竟,揭...
安卓系统铠无法兑换,揭秘无法兑... 最近是不是有很多小伙伴在玩安卓系统的游戏,突然发现了一个让人头疼的问题——铠无法兑换!别急,今天就来...
汽车安卓系统崩溃怎么刷,一键刷... 亲爱的车主朋友们,你是否曾遇到过汽车安卓系统崩溃的尴尬时刻?手机系统崩溃还能重启,但汽车系统崩溃了,...
miui系统可以刷安卓p系统吗... 亲爱的手机控们,你是否对MIUI系统情有独钟,同时又对安卓P系统的新鲜功能垂涎欲滴?今天,就让我带你...