概念
正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
虽然之前从来没有了解过有关正则表达式的观念,但是在接触电脑的途中例如:我们很可能使用?和*通配符来查找硬盘上的文件。 ?通配符匹配文件名中的0个或1个字符,而*通配符匹配零个或多个字符。像data(\w)?\.dat这样的模式将查找下列文件:
data.dat
data1.dat
data2.dat
datax.dat
dataN.dat
使用*字符代替?字符扩大了找到的文件的数量。data.*\.dat匹配下列所有文件:
data.dat
data1.dat
data2.dat
data12.dat
datax.dat
dataXYZ.dat
正则语法
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。
正则表达式 – 元字符 | 菜鸟教程 (runoob.com)
[abc]表示匹配 [...] 中的所有字符,[abc]就表示匹配当前的所有a,b,c字母
![](https://i-blog.csdnimg.cn/blog_migrate/729eae7a3a04867fc97735386d82d745.png)
特殊字符
所谓特殊字符,就是一些有特殊含义的字符,如上面说的 runoo*b 中的 *,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 符号,则需要对 * 进行转义,即在其前加一个 \,runo\*ob 匹配字符串 runo*ob。
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:
特别字符 | 描述 |
$ | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 \$。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。例如:do(es) |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。 |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。 |
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 \[。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\",而 '\(' 则匹配 "("。 |
^ | 匹配输入字符串的开始位置,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 \{。 |
| | 指明两项之间的一个选择。要匹配 |,请使用 \|。 |
$
匹配以某个字符结尾的数据
![](https://i-blog.csdnimg.cn/blog_migrate/ec87a55b07ebd9640939adea3fefb050.png)
^
匹配输入字符串的开始位置
当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。
匹配由任意数字开头一个的字符
![](https://i-blog.csdnimg.cn/blog_migrate/b47ee7b316d90f75efd1a0434115a448.png)
表示匹配所有除了方括号以外的字符
![](https://i-blog.csdnimg.cn/blog_migrate/a852f3cb67aa9d802a0f05909b0efd10.png)
^和$
当两种特殊字符一起使用时表示整行匹配
只匹配由abc组成的行
![](https://i-blog.csdnimg.cn/blog_migrate/c8dc3036cccb8dad45a37c094a62c087.png)
表示只配由字母组成的行
![](https://i-blog.csdnimg.cn/blog_migrate/7524dbe1224f085d71b4b78e2e427332.png)
( )
我们可以利用()来确定需要匹配的子字符串,标记一个子表达式的开始和结束位置。
![](https://i-blog.csdnimg.cn/blog_migrate/a4b79daef69e035feb6ee14bff2fecd7.png)
|
或符号,指明两项之间的一个选择。
这里表示匹配a开头+(以b或c)组成的字符串
![](https://i-blog.csdnimg.cn/blog_migrate/890102a98adf19a8781cc3928e7ee75f.png)
.
匹配除了换行符\n以外的所有单字符
可以看到,如果abc之后没有任何除\n以外的符号的话是不会被匹配到的
![](https://i-blog.csdnimg.cn/blog_migrate/063daf5924b023490036017aed79afee.png)
限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。
正则表达式的限定符
字符 | 描述 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于 {0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,zo+ 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 "do" 、 "does"、 "doxy" 中的 "do" 和 "does"。? 等价于 {0,1} |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 "Bob" 中的 o,但是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 "Bob" 中的 o,但能匹配 "foooood" 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。 |
{n,m} | m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 "fooooood" 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。 |
*
匹配前面的子表达式零次或多次。
这里就意味着匹配z开头+以零个或多个o组成的字符串
![](https://i-blog.csdnimg.cn/blog_migrate/869440a0aab30af26aaba094a9bb5be9.png)
+
匹配前面的子表达式一次或多次。
这里表示匹配z开头+以一个或多个o组成的字符串
![](https://i-blog.csdnimg.cn/blog_migrate/1d5859c0035d452a9e723c308bbe3b1f.png)
?
匹配前面的子表达式零次或一次。
这里的()小括号可以看作一个整体,这里就表示匹配do开头+零个或一个es组成的字符串
![](https://i-blog.csdnimg.cn/blog_migrate/bac4d9e4b75e0fe9ea149d78790bdc5a.png)
{n}
n 是一个非负整数。匹配确定的 n 次。
因为是匹配两次所以不会匹配does,而是会匹配do开头+两个es组成的字符串
![](https://i-blog.csdnimg.cn/blog_migrate/25c60b58aa0feae3c921961bd64137f4.png)
{n,}
n 是一个非负整数。至少匹配n 次
这里表示至少匹配2次c
![](https://i-blog.csdnimg.cn/blog_migrate/f5b9daa716b585f24ce5c7273d797e16.png)
{n,m}
m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。
至于这里为啥会一个字符串出现匹配多个的情况,暂时还不了解
![](https://i-blog.csdnimg.cn/blog_migrate/03b395c960edad9280c321a7248184e4.png)
修饰符(标记)
标记也称修饰符,正则表达式的标记用于指定额外的匹配策略。标记不写在正则表达式里,标记位于表达式之外
修饰符 | 含义 | 描述 |
i | ignore - 不区分大小写 | 将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。 |
g | global - 全局匹配 | 查找所有的匹配项。 |
m | multi line - 多行匹配 | 使边界字符 ^ 和 $ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。 |
s | 特殊字符圆点 . 中包含换行符 \n | 默认情况下的圆点 . 是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。 |
g全局匹配
假如没有g修饰符,就只会匹配第一次查询到的数据,对于后面出现的abc则没有高亮显示
![](https://i-blog.csdnimg.cn/blog_migrate/db91bd5f57e27edf0c8a94f333c4bad3.png)
添加了修饰符则表示全局搜索,匹配所有符合条件的数据
![](https://i-blog.csdnimg.cn/blog_migrate/117e9af2b65431b9ebbb0c4ad6c89713.png)
m多行匹配
若存在换行\n并且有开始^或结束$符的情况下,和g一起使用实现全局匹配
很清楚看到单单使用g作为修饰符作全局搜索也不会匹配到第二行的abc
![](https://i-blog.csdnimg.cn/blog_migrate/144b271aa438b3112b2867699ad1dd85.png)
我理解的是:因为存在换行时也会把换行符作为一个字符,识别匹配字符串是个单行,
g只匹配第一行,添加m之后实现多行,每个换行符之后就是开始
![](https://i-blog.csdnimg.cn/blog_migrate/faed2c4ab5ee1bb0a2db0493c9cae7e4.png)
i不区分大小写
匹配字符也是区分大小写的
![](https://i-blog.csdnimg.cn/blog_migrate/a59c4440f2c0b510f33316678f36926e.png)
在添加i作为修饰符后就可以不区分大小写匹配任何带有abc的数据
![](https://i-blog.csdnimg.cn/blog_migrate/f5bd0d8c93204dd8984a1f7d37985db6.png)
s特殊字符圆点 . 中包含换行符 \n
默认情况下.圆点是不会匹配换行符的
![](https://i-blog.csdnimg.cn/blog_migrate/25e56220e0b4223eff05ce0381f7d114.png)
添加s修饰符后就会在原先的基础上匹配到换行符
![](https://i-blog.csdnimg.cn/blog_migrate/c027409b3e3845d5ca545b1e84ad867d.png)
元字符
https://www.runoob.com/regexp/regexp-metachar.html
<?php
$var = "abcd test@runoob.com 1234";
preg_match_all('/\b[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,6}\b/',$var, $matches);
print_r( $matches)
?>
![](https://i-blog.csdnimg.cn/blog_migrate/3cbb1a9d26c85c012f883179dd2fade3.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0bf26624fdde360e6ebcf55da43d7ea5.png)
另外在php的正则表达式中好像是没有修饰符g的,在PHP中通常使用preg_match_all来表示全局搜索