【 通过例子学习正则表达式 Day1 】
【例一】找出以 lefe
或 lefe_x
单词开头,以 wsy
结尾的字符串。比如:lefe name is wsy
是合法的,而 lef name is wsy
是非法的。
【正则表达式为】
"(^(?:lefe|lefe_x)\b.{0,}wsy$)"
-
^
表示从字符串的开始位置匹配,^(?:lefe|lefe_x)
表示以lefe
或者lefe_x
开头; -
|
表示或,比如 A | B | C ,表示 A,B 和 C 中任意一个; -
()
表示一个组,(?:)
表示不捕获这个分组; -
\b
表示匹配一个单词的边界,在这里只能匹配lefe
和lefe_x
; - 匹配字符串的开头和结尾后,基本上完成了题目的要求,但是字符串
lefe
(lefe_x)和wsy
之间可以是任意字符,.
表示匹配任意字符(不包含换行符),{0,}
表示匹配0个或多个字符,则.{0,}
表示匹配0个或多个任意字符(不包含换行符); -
$
表示从字符串的结尾处开始匹配,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]
【 通过例子学习正则表达式 Day2 】
正则表达式对于每一种语言来说都十分重要,然而很多同学可能仍然停留在复制粘贴中。其实学好正则表达式有时非常必要,起码可以阅读它,更好的情况是能够书写它。本文主要通过【例子+图片】的方式来学习它,旨在能够让每位朋友更轻松的学习,在几天的学习结束后会给大家一个总结。
【例子2】匹配以 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
【 通过例子学习正则表达式 Day3 】
【例3】匹配由数字和字母组成的 6-16 位字符串。
【分析】
- 数字和字母组成,可以表示为:
[0-9a-zA-Z]
; - 6-16位字符,可以表示为
{6,16}
; - 由数字和字母组成,则不能为纯数字和纯字母组成的。
【正则表达式】
’^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$‘
【解析】
?!
在【例2】中已说明,(?![0-9]+$)
不能为纯数字,(?![a-zA-Z]+$)
不能纯字母。
【例4】匹配 html 标签,比如 <body>Hello lefe</body>。
【分析】
html 标签为成对出现的,比如<body></body>,<title><title>
【正则表达式】
^<([a-z]+)>.*<\/\1>
【知识点】
\数字
:表示引用分组,\1
表示匹配分组1
【 通过例子学习正则表达式 最后一天 】
如果你跟着前3天的学习,基本上已经掌握了正则表达式,不过需要多加练习,这样会理解更加深刻。前几天的例子都是通过 Python 验证的,在 iOS 中正则表达式的实现可能与 Python 有少许不同。今天主要总结各个字符代表的含义:
-
^
: 从字符串开始位置匹配,^lefe:以 lefe 开头的文本; -
$
: 从字符串的结尾匹配,$lefe:以 lefe 结尾的文本; -
*
: 匹配0个或多个字符,lefe*:lef 后出现0个或多个e,lef,lefeeee 合法; -
+
: 匹配1个或多个字符,lefe+:lef 后出现1个或多个e,lefe,lefeeee 合法; -
?
: 匹配0个或者1个字符,lefe?:lef 后出现0个或1个e,lef,lefe 合法; -
{m}
: 匹配 m 次,lefe{2}: lefe 后出现 1 个 e,lefee 合法; -
{m,}
: 匹配至少 m 次,lefe{2,}: lefe 后至少出现 1 个 e,lefee,lefeee 合法; -
{m,n}
: 匹配 m dao n 次,lefe{2,3}: lefe 后出现 1 个 或者 2 个 e,lefee,lefeee 合法; -
\d
: 匹配任意0-9的数字,比如:123,23; -
\D
: 与 \d 相反,匹配不是0-9的字符,比如:lefe; -
\w
: 匹配任何数字和字母,还有下划线,比如:lefe_x; -
\W
: 与 \w 相反; -
\s
: 匹配任何空格字符,与 [\n\t\r\f] 相同; -
\S
: 与 \s 相反; -
\b
: 匹配单词边界,比如使用正则表达式'\w*\b' 匹配 'lefe_x is wsy',将匹配到 lefe_x,is 和 wsy; -
\B
: 与 \b 相反; -
[字符]
: 匹配[]中的任意单个字符,比如[lefx] 匹配 l,e,f 和 x 中的任意一个字符; -
[^字符]
: 匹配除[]中的任意单个字符,比如[lefx] 匹配除了 l,e,f 和 x 的任意字符; -
[a-z]
: 匹配 a 到 z 任意字母; -
A|B|C
: 只能匹配 A,B 和 C 的任意一个,lefe|lefe_x|wsy 匹配 lefe 或 lefe_x 或 wsy; -
.
: 匹配除 \n,\r 任何单个字符; -
()
: 分组,可以获取分组中的内容,比如:'\[UIImage imageNamed:@"(.+?)"'
,匹配[UIImage imageNamed:@"lefe"]
可以从匹配结果中获取到图片的名字 lefe; -
\数字
:引用分组,比如:^<([a-z]+)>.*<\/\1>' 可以匹配
<body>hello lefe</body>` -
(?:)
: 非获取匹配,在匹配结果中将忽略这个分组; -
(?=)
: 非获取匹配,正向肯定预查,正则表达式'window(?=98|95|2000)'
可以匹配window98
或window95
或window2000
中的window
; -
(?!)
: 非获取匹配,正向否定预查,正则表达式'window(?!98|95|2000)'
可以匹配window2007
中的window
, 不可以匹配window98
或window95
或window2000
中的window
; -
(?<=)
: 非获取匹配,反向肯定预查,正则表达式'(?<=98|95|2000)window'
可以匹配98window
或95window
或2000window
中的window
; -
(?<!)
: 非获取匹配,反向否定预查,正则表达式'(?<!98|95|2000)window'
可以匹配2007window
中的window
, 不可以匹配98window
或95window
或2000window
中的window
;
最后给大家推荐一个 可视化正则表达式网站
推荐阅读
【iOS 国际化】如何把国际化时需要3天的工作量缩减到10分钟
===== 我是有底线的 ======
喜欢我的文章,欢迎关注我的新浪微博 Lefe_x,我会不定期的分享一些开发技巧