一、普通字符:字母或数字;
注:这样的正则表达式会优先匹配最长字符串,比如输入 I had an aaaaawful day
会匹配单词aaaaawful中的aaaaa,而不会匹配其中的aaa。
重复次数是可以有范围的,但是有时候这样的方法也不能找到最佳答案。如果你的输入文本是I had an aaawful daaaaay那么在第一次匹配时,只能找到aaawful,只有再次执行匹配时才能找到daaaaay中的aaaaa。
二、元字符:
(1) “ . ” :表示可以匹配任一字符;
eg:“ c.t ” 可以匹配 “ cat ”,“ cot ” 等字符;
注:在字符类中只表示一个普通字符 “ . ”;
(2)“ \ ” :可以令一元字符失效,变为普通字符;
eg:“ c\.t ” :可以匹配 “ c.t ”;
注:在字符类中也作用相同;
(3)字符类 “ [ ] ”:表示可以匹配括号其中的任一字符;
eg:“ c[aeiou]t ”:表示可以匹配 " cat "、“ cet ”、“ cit ”、“ cot ” 、“ cut ”;
注:
1、在字符类中,字符的重复和出现顺序并不重要。“ [dabaaabcc] ” 与 “ [abc] ” 是相同的。
2、在字符集中,你可以通过使用短横线来表示匹配字母或数字的范围。
eg:
- “ [b-f] ”与“ [b,c,d,e,f] ”相同,都是匹配一个字符”b”或”c”或”d”或”e”或”f”
- “ [A-Z] ”与“ [ABCDEFGHIJKLMNOPQRSTUVWXYZ] ”相同,都是匹配任意一个大写字母。
- “ [1-9] ”与“ [123456789] ”相同,都是匹配任意一个非零数字。
3、重要提示:字符类中和字符类外的规则有时不同,一些字符在字符类中是元字符,在字符类外是普通字符。一些字符正好相反。还有一些字符在字符类中和字符类外都是元字符,这要视情况而定!
实例:匹配YYYY-MM-DD格式的日期:
“ [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ”
(4)字符类的反义:你可以在字符类的起始位放一个反义符。
- [^a]表示匹配任何不是“a”的字符
- [^a-zA-Z0-9]表示匹配任何不是字母也不是数字的字符
- [\^abc]匹配一个为“^”或者a或者b或者c的字符
- [^\^]表示匹配任何不为“^”的字符
(5)转义字符类:
- \D与[^0-9]相同,表示匹配一个非数字字符
- \d这个正则表达式与[0-9]作用相同,都是匹配任何一个数字
- \W与[^0-9A-Za-z]相同,表示匹配一个非数字同时不是字母的字符
- \w与[0-9A-Za-z]相同,都表示匹配一个数字或字母字符
- \S表示匹配一个非空字符
- \s意味着匹配一个空字符(空格,制表符,回车或者换行)
实例:简化正则表达式“ [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ”
“ \d\d\d\d-\d\d-\d\d ”
(6)重复:在字符或字符集之后,你可以使用{ }大括号来表示重复。
- 正则表达式a{1}与a意思相同,都表示匹配字母a
- a{3}表示匹配字符串“aaa”
- a{0}表示匹配空字符串。从这个正则表达式本身来看,它毫无意义。如果你对任何文本执行这样的正则表达式,你可以定位到搜索的起始位置,即使文本为空。
- a\{2\}表示匹配字符串“a{2}”
- 在字符类中,大括号没有特殊含义。[{}]表示匹配一个左边的大括号,或者一个右边的大括号
eg:简化下面的正则表达式
z.......z
\d\d\d\d-\d\d-\d\d
[aeiou][aeiou][aeiou][aeiou][aeiou][aeiou]
[bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz]
答案:
z.{7}z
\d{4}-\d{2}-\d{2}
[aeiou]{6}
[bcdfghjklmnpqrstvwxyz]{10}
注:重复次数可以有范围:
(1)重复次数是可以指定范围的:
- x{4,4}与x{4}相同
- colou{0,1}r表示匹配colour或者color
- a{3,5}表示匹配aaaaa或者aaaa或者aaa
(2)重复次数的范围可以是开区间:
- a{1,}表示匹配一个或一个以上的连续字符a。依然是匹配最长字符串。当找到第一个a之后,正则表达式会尝试匹配尽量多个的连续字母a。
- .{0,}表示匹配任意内容。无论你输入的文本是什么,即使是一个空字符串,这个正则表达式都会成功匹配全文并返回结果。
eg:
(1)使用正则表达式找到双引号。要求输入字符串可能包含任意个字符。
".{0,}"
(2)调整你的正则表达式使得在一对双引号中间不再包含其他的双引号。
" [^"]{0,} "
(7)关于重复的转义字符:
-
?与{0,1}相同,比如,colou?r表示匹配colour或者color,字符类中为普通字符;
-
* 与{0,}相同。比如,.*表示匹配任意内容,在字符类中为普通字符;
-
+与{1,}相同。比如,\w+表示匹配一个词。其中”一个词”表示由一个或一个以上的字符组成的字符串,在字符类中为普通字符;
eg:简化下列的正则表达式:
".{0,}"
and"[^"]{0,}"
x?x?x?
y*y*
z+z+z+z+
答案:
".*"
and"[^"]*"
x{0,3}
y*
z{4,}
(8)非贪婪匹配:字符串默认为贪婪匹配,即默认匹配字符最多的字符串;通过在句尾加上一个问号,可以使得字符串不再匹配最长字符。
eg:
- \d{4,5}?表示匹配\d\d\d\d,也就是和\d{4}一样
- “.*?”表示先匹配一个双引号,然后匹配最少的字符,然后是一个双引号,这很有用。
(9)选择匹配:你可以使用|来分隔可以匹配的不同选择:
- cat|dog表示匹配”cat”或者”dog”
- red|blue|以及red||blue以及|red|blue都表示匹配red或者blue或者一个空字符串
- a|b|c与[abc]相同
- cat|dog|\|表示匹配”cat”或者”dog”或者一个分隔符”|“
- [cat|dog]表示匹配a或者c或者d或者g或者o或者t或者一个分隔符“|”
eg:简化下列正则表达式:
aa|ab|ba|bb
[abc]|[^abc]
[^ab]|[^bc]
[ab][ab][ab]?[ab]?
答案:
[ab]{2}
.
[^b]
[ab]{2,4}
注:使用正则表达式匹配1到31之间的整数,[1-31]不是正确答案!
这样的正则表达式不唯一. [1-9]|[12][0-9]|3[01]
是其中之一。
(10)分组:使用()来进行分组;
eg:
- 通过使用 (Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day 匹配一周中的某一天
- [()]表示匹配任意一个左括号或者一个右括号
分组可以包括空字符串:
- (red|blue)表示匹配red或者blue或者是一个空字符串
你也可以在分组的基础上使用重复:
- (red|blue)?与(red|blue|)相同
练习:
简化正则表达式 \w+\W+\w+\W+\w+
以及 \w+\W+\w+\W+\w+\W+\w+\W+\w+\W+\w+
.
答案:
\w+(\W+\w+){2}
以及 \w+(\W+\w+){5}
.
(11)单词分界符:如果使用 tm 可以匹配在字符串中出现的任何位置,例如 html ,utmost 也会被查找出来。但如果要匹配的是单词 tm ,而不是某一字符的一部分,这时可以用单词分界符 \b 来查找一个完整的单词。
eg:\b tm \b
\B tm \B 的作用与 \b 相反,它匹配的 tm 必须是其它单词的一部分;
(12)换行符:
- ^表示匹配行的开始位置
- $表示匹配行的结束位置
- ^&表示一个空行
^.*&
表示匹配全文内容,因为行的开始符号也是一个字符,"."会匹配这个符号。找到单独的一行,可以使用
^.*?$- \^\$表示匹配字符串“^$”
- [$]表示匹配一个$。但是,[^]不是合法的正则表达式。记住在方括号中,字符有不同的特殊含义。要想在方括号内匹配^,必须用[\^]
(13)文本分界:在很多的正则表达式实现中,将^和$作为文本的开始符号和结束符号。还有一些实现中,用\A和\z作为文本的开始和结束符号。
eg:
信用卡号
在一个网站上,我输入了我的卡号比如 1234 5678 8765 4321
网站拒绝接收。因为它使用了正则表达式\d{16}。
正则表达式应该考虑到用户输入的空格和短横线。
实际上,为什么不先过滤掉所有的非数字字符,然后再进行有效性验证呢?这样做,可以先使用\D以及空的替换表达式。
练习
在不先过滤掉所有的非数字字符的情况下,使用正则表达式验证卡号的正确性。
答案
\D*(\d\D*){16}
is one of several variations which would accomplish this.