把必须匹配的情况考虑周全并写出一个匹配结果符合预期的正则表达式很容易,但把不需要匹配的情况也考虑周全并确保他们都将被排除在匹配结果以外往往要困难得多
– Ben Forta
2.匹配单个字符
正则表达式是由一些字符构成的字符串,包含普通字符和元字符
.
可以匹配任何字符(除换行符以外)
\
用来对字符进行转义,匹配 \
使用 \\
3.匹配一组字符
- 元字符
[
和]
用来定义一个字符集合,其含义是必须匹配该集合里的字符之一 - 定义字符可以用列举法,也可以用元字符
-
以字符区间的方式定义 - 字符集合可以使用
^
来求非,这在匹配时将排除集合内字符,其他字符都可以被匹配
4.使用元字符(见附)
5.重复匹配
+
匹配字符或字符集合的一次或多次重复
*
匹配字符或字符集合的零次或多次重复
?
匹配字符或字符集合的零次或一次出现
{m}、{m , }、{m , n}
精确设定匹配重复次数
- 除了
?
以外,其他均为“贪婪型”元字符 - 如果要防止过度匹配,使用“懒惰型”元字符,即在“贪婪型”元字符后加上
?
元字符
6.位置匹配
- 正则表达式还可以用来匹配出现在字符串中特定位置的文本
\b
用来指定一个单词边界 (\B
刚好相反 )^
和$
用来指定字符串边界 ( 字符串的开头和结束 ) - 如果与
(?m)
配合使用,^
和$
将匹配任意一行字符串的开头和结束,(?m)
必须在整个模式的最前面;此时,换行符将被视为一个字符串分隔符
7.使用字表达式
- 子表达式用
(
和)
来定义,字表达式的常见用途包括:对重复次数元字符的作用对象做出精确的设定和控制、对|
操作符的OR
条件做出准确的定义等。如有必要,字表达式还允许嵌套使用。 - 例如匹配一个合法的IP地址(不能匹配非法IP地址)的正则表达式如下:
(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))
8.回溯引用,前后一致匹配
- 使用
(
和)
定义一个子表达式,在后续语句中使用\1、\2、...
来引用已定义的第1、2、…个子表达式,以此来匹配与子表达式1、2、…一致的内容,有的正则表达式使用$1、$2、...
。 - 回溯引用也多用在匹配后替换操作中
\0
或$0
代表整个正则表达式
9.前后查找
- 前后查找操作使我们可以利用子表达式来指定文本匹配操作发生的位置,并收到只匹配不消费(不会匹配前后查找子表达式中的字符)的效果。
- 正向前查找用
(?=)
来定义,负向前查找用(?!)
来定义。有些正则表达式还支持正向后查找(?<=)
和负向后查找(?<!)
10.嵌入条件(回溯引用条件)
例:匹配可接受北美电话号
(123-456-7890
1234567890
123 456 7890
正则表达式
(\()?\d{3}(?(1)\)|-)\d{3}-\d{4}
分析
用 (
和 )
将 \(
定义为子表达式,后面接一个?
代表可选匹配项(?(1)\)|-)
中 ?(1)
将判断子表达式1是否匹配,如果匹配则必须匹配 \)
,若不匹配则必须匹配 -
(pattern X )?pattern(?(X)pattern|pattern)
X为子表达式计数
嵌入前后查找条件略