1. 匹配单个字符
1.1 任意字符
.
可以匹配任意单个除了换行符的字符。
例:
机器学习
链接: https://pan.baidu.com/s/1o9hlR5o 密码: 6iih
.
机器学习
链接: https://pan.baidu.com/s/1o9hlR5o 密码: 6iih
1.2 特殊字符(转义)
假如对这个例子,我们像匹配"pp."
napp.txt napptxt makk.txt
如果使用 pp.
,匹配结果为:
napp. txt napptxt makk.txt
如果要匹配 .
,就要使用转义字符
pp\.
napp. txt napptxt makk.txt
2. 匹配一组字符
可以使用 []
来定义一个字符集合,用于匹配属于该集合的字符。
[mn]a
napp. txt napptxt makk.txt
2.1 使用字符区间
对于文本:
nam.txt na1.txt ma4.txt mb.txt
像要匹配如“m或n a 数字”的话,可以使用字符区间:
[mn]a[0-9]
nam.txt na1.txt ma4.txt mb.txt
字符区间准确而言是在ASCII中的子区间,因此可以是:
- A-Z
- a-z
- 0-9
- A-F
另外注意两点:
-
只在[]
中才有特殊含义,所以一般使用是不需要转义- 不要出现类似
[3-1]
这种反序的区间
2.1.1 匹配中文字符
[\u4e00-\u9fa5]
2.2 取非匹配
可以在 []
中的开头使用 ^
字符表示取反操作:
[mn]a[^0-9]
nam.txt na1.txt mb.txt
另外有两点:
^
将对[]
中所有字符取反,而非仅仅是它后面的那个^
要放在开头
3. 元字符
3.1 转义问题
元字符指的是那些有着特殊含义的字符,如 .
、[]
等。不能使用这些元字符匹配其字面字符,必须使用转义。比如对于:
int[] arr = new int[5];
arr[0] = 1;
arr[1] = 2;
如果使用 arr[[0-9]]
试图匹配的话什么都匹配不到,必须要:
arr\[[0-9]\]
int[] arr = new int[5];
arr[0] = 1;
arr[1] = 2;
同理,比如我们希望把windows风格的路径变为Unix风格的。 > C:
如果使用 \
的话什么都匹配不到,必须使用 \\
。
3.2 空白字符
常用的空白字符包括:
\t
,\n
,\r
,\f
(换页符),\v
(垂直制表符)
可以使用 \s
来表示上面所有符号的集合,等价于 [\t\n\r\f\v]
。
另外 \S
表示所有非空白符,等价于 [^\t\n\r\f\v]
。
3.3 数字
\d
: 等价与[0-9]
\D
: 等价与[^0-9]
3.4 有效英文字符
\w
: 等价于[0-9A-Za-z_]
(数字字母下划线)\W
4. 重复匹配
4.1 ?
、+
和 *
?
: 匹配零次或一次*
: 匹配零次或多次+
: 匹配一次或多次
4.2 使用{}
- 指定次数
使用{n}
表示重复n
次 - 设定区间
- 使用
{m, n}
表示最少重复m
次,最多n
次 - 使用
{m,}
表示至少重复m
次
- 使用
4.3 防止过度匹配
以上所有的重复匹配,都默认是贪婪型的,它们会尽可能的匹配多的字符而不是在第一个匹配位置就结束。
A <B>utf-8</B> B <B>GBK\</B>
<B>.*</B>
A <B>utf-8</B> B <B>GBK</B>
为了改为“懒惰型”,只需要在最后加上?
即可:
*?
+?
{m, }?
<B>.*?</B>
A <B>utf-8</B> B <B>GBK</B>
5. 位置匹配
5.1 单词边界
The cat scattered his food
cat
The cat scattered his food
使用\b
可以限定单词边界,他匹配的是一个位置。
\bcat\b
The cat scattered his food
5.2 字符串边界
^
$
6. 子表达式
使用()
括在一起地被视为一个子表达式,是一个整体。
7. 回溯引用
回溯引用指的是可以引用待匹配字符串中其中一部分,为了具体说明首先我们来看一个例子。
假如我们有下面这段文本:
<h1>ddd<h1>
<h1>ddd<h2>
我们希望能够匹配到符合规则的HTML标签,也许可以这样:
<h\d>.*?<h\d>
很遗憾,这样做会把第二个不合法的标签也囊括进来:
<h1>ddd<h1>
<h1>ddd<h2>
所以我们需要能够引用之前能匹配的子串,具体做法就是使用回溯引用:
(<h\d>).*?\1
结果为:
<h1>ddd<h1>
<h1>ddd<h2>
这里使用了子表达式和回溯引用的方法,\1
表示引用第一个子表达式。可以把它想象成一个变量,使用“变量名”\1
来引用。
一般而言,回溯引用常常从1开始计数(\1
, \2
等等)
8. 零宽断言
零宽断言是正则表达式的一种方法,用于查找在某些内容(但并不包括这些内容)之前或者之后的东西,也就是说他们像 \b
,^
(匹配输入字行首),$
(匹配输入字行尾)那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。
断言用来声明一个应该为真的事实,正则表达式中只有当断言为真时才会继续进行匹配。
8.1 零宽度正预测先行断言
(?=exp)
叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。
比如 \b\w+(?=ing\b)
,匹配以ing结尾的单词的前面部分(除了ing以外的部分)。
I'm singing while you're dancing
\b\w+(?=ing\b)
I'm singing while you're dancing
8.2 零宽度正回顾后发断言
(?<=exp)
也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。
比如 (?<=\bre)\w+\b
会匹配以re开头的单词的后半部分(除了re以外的部分)。
reading a book
(?<=\bre)\w+\
reading a book
不过这个特性不一定每个实现都支持。