正则表达学习
正则表达学习
在线正则表达式测试地址 <- 点我
Sample1:
找出以
lefe
或lefe_x
单词开头,以wsy
结尾的字符串。比如:lefe name is wsy
是合法的,而lef name is wsy
是非法的。
正则表达式为:(^(?:lefe|lefe_x)\b.{0,}wsy$)
1.^
表示从字符串的开始位置匹配,^(?:lefe|lefe_x)
表示以 lefe
或者 lefe_x
开头;
2. |
表示或,比如 A | B | C ,表示 A,B 和 C 中任意一个;
3. ()
表示一个组,(?:)
表示不捕获这个分组;
4. \b
表示匹配一个单词的边界,在这里只能匹配 lefe
和 lefe_x
;
5.匹配字符串的开头和结尾后,基本上完成了题目的要求,但是字符串lefe
(lefe_x)和wsy
之间可以是任意字符,.
表示匹配任意字符(不包含换行符),{0,}
表示匹配0个或多个字符,则.{0,}
表示匹配0个或多个任意字符(不包含换行符);
6.$
表示从字符串的结尾处开始匹配,wsy$
则表示以 wsy
结尾;
【 知识点 】
- 字符边界
^
,$
和\b
表示字符的边界,^
匹配字符串的开头,$
匹配字符串的结尾,\b
匹配单词的边界,如:lefe\b
可以匹配lefe
,但不可匹配lefe_x
; - 量词
{m} 只出现 m 次,lefe{2} 只能匹配 lefee
{m,n} 出现 m 到 n 次
{m,} 至少出现 m 次 - 选择表达式
比如 lefe | Lefe_x | Lefe ,表示 lefe,Lefe_x 和 Lefe 中任意一个 - 分组
以括号括起来的字符集为一个分组,在 ( 添加 ?: 将忽略这个分组 ) - 字符集
. 匹配除换行符以外的任意一个字符
\w = [0-9a-zA-Z_]
\W = [^0-9a-zA-Z_]
\s = [\t\n\v]
\S = [^\t\n\v]
\d = [0-9]
\D = [^0-9]
正则表达式分组()、不捕获(?:)
分组
分组在正则中用()表示,分组的作用有两个:
1.将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。
2.分组之后,可以通过后向引用简化表达式(\1 或者$1)。
分组举列
先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式:
\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
但仔细观察,可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下:
\d{1,3}(.\d{1,3}){3}
再来看第二个作用,就拿匹配
<title>.*</title>
可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:
<(title)>.*</\1>
对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。 [(xxx) 一个括号等于一个分组]
注意:
用\1这种语法,可以引用某组的文本内容,但不能引用正则表达式。
例如刚刚的IP地址正则表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下:
错误示范:(\d{1,3})(.\1){3}
后向引用,引用的仅仅是文本内容,而不是正则表达式!
也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。
因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。
不捕获
不捕获就是在分组的前边加上?:
,可以在不需要捕获分组的表达式中使用,加快表达式执行速度。
就拿匹配
<(title)>.*</\1>
但是如果是 (?:title)
,则\1就不能捕获到这个子组了,只能捕获第一个出现的非 ?:
的分组作为\1
同时注意(?:title)本身会在完整匹配中,只是不在子组中,注意和断言的区别
1 | $str="ab123ff"; |
Sample2 :
匹配以 lefe
开头,lefe
后面不能紧跟_x
,后面由数字,-,_和字母组成,且不包含l,e,f 三个字母中的任意一个(至少一位),且为最短的用户名
【分析】
根据要求可以把题目拆分成:
1.以 lefe
开头,不能为 lefe_x
。可以转换成 ^lefe(?!_x)
;
2.中间部分由数字,-,_和字母组成,不能包含 l,e,f,至少一位。可以转换成 [0-9a-dg-km-zA-DG-KM-Z_-]+
;
3.匹配最短的。在正则表达式中用到了贪婪与非贪婪的概念,使用 ?
;
【正则表达式】
^(lefe(?!_x)(?:[0-9a-dg-km-zA-DG-KM-Z_-]+?)
知识点
1.非获取匹配
lefe(?=_x) ,lefe 后面紧跟着 _x,正向肯定预查
lefe(?!_x) ,lefe 后面不能出现 _x,正向否的定预查
(?<!lefe)_x ,_x 前面不能为 lefe,反向肯定预查
(?<=lefe)_x ,_x 前面为 lefe,反向否的定预查
2.字符集合
[xyz] 匹配 x,y,z 任意一个字符;
[^xyz] 匹配除 x,y,z 外的任意一个字符;
[a-z] 匹配 a-z 中任意一个字符;
3.贪婪匹配与非贪婪匹配
默认的匹配规则为非贪婪匹配,使用 ?
使贪婪匹配变为非贪婪匹配。比如:使用正则表达式lefe{2,}
匹配 lefeeeeeeee
,如果为贪婪匹配(lefe{2,}
)时将匹配 lefeeeeeeee
,为非贪婪匹配(lefe{2,}?
)时,将匹配 lefee
。
4.量词 *
,+
,?
'lefe*'
,lef 后有0个或多个e'lefe+'
,lef 后有1个或多个e'lefe?'
,lef 后有0个或1个e