分组
() 是有分组提取功能的。如提取电话号码可以/(\d{4})\-(\d{7})/
,就会把1111-1111111
的电话号码提取为1111
和1111111
。
如果想使用分组的功能,但是又不想提取,就可以使用(?:)。如提取电话号码/(?:\d{4})\-(\d{7})/
,就只会提取出后七位1111111
。
分组使用示例:提取日期
日期格式各种各样,如:
2022-05-09
2022-5-9
20220509
2022 5 9
2022.05.09
统一提取这些不同格式日期的方法:用[]处理年月日分隔处可能出现的字符。
(\d{4})[\-\. ]?(\d{1,2})[\-\. ]?(\d{1,2})
[]里的内容表示分隔符可能是-,.,空格,还可能没有(用?处理)。
(\d{1,2})表示月日可能1位或2位。
分组的回溯引用
对于刚才分组得到的数据,可以通过反向引用来获取。
如查询 abcabc 式的数据:/(abc)(\1)/
.
查询abcdefdefabc:/(abc)(def)(\2)(\1)/
.
先行断言
或者叫环视、预搜索。
正向先行断言
(?=表达式),指在某个位置向右看,表示所在位置右侧必须能匹配表达式
。
如:/我爱(?=你)
表示我爱右边必须要有你。
检验密码中必须要有大写和小写字母:
(?=.*?[a-z])(?=.*?[A-Z]).+
检验密码中必须要有大写小写字母、数字,长度还要>=8:
(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9]).{8,}
反向先行断言
(?!表达式),指在某个位置向右看,表示所在位置右侧必须不匹配表达式
。
如:/我爱(?!你)
表示我爱右边必须没有你。
正向后行断言
(?>=表达式),从右往左看。
如:(?<=我)爱你
表示爱你左边必须有我。
反向后行断言
(?>!表达式)
如:(?<!我)爱你
表示爱你左边必须没有我。
例题
匹配质数个x。如xx,xxx,xxxxx。
首先,质数只能被1和它自身整除。所以只需要排除掉可以被2整除,被3整除,被4整除……的数即可。也就是2以上的数字要重复出现两次以上。
出现2以上的数字次数的x是(..+),但是不能用(..+)+,因为+号并不保证每次括号内的字符数相同(可能是2+3+4+……)。所以要用\1反向引用(..+),再让\1重复出现1次以上,因此(..+)\1+就是任意一个>2的数* 任意一个>=2的数,涵盖了所有合数。
最后取反,再限制一下行首行尾就能得出所有质数。有一个小问题好像这样会把x也看做质数。
因此答案是:^(?!(..+)\1+$)
.