正则表达式
1.正则表达式的定义
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式(Regex)是一种强大的文本模式匹配工具,用于对字符串进行搜索、替换和验证。它利用一组特定的字符和元字符,构成规则字符串,从而定义如何识别和操作文本。总的来说正则表达式就是一串满足能够满足过滤要求,并且能够进行规则匹配的字符串。
2.匹配规则
2.1单个字符匹配
代码 | 功能 |
---|---|
. | 匹配任意一个字符(除了/n) |
[ ] | 匹配[ ]中列举的字符 |
\d | 匹配数字字符,0-9 |
\D | 匹配非数字字符 |
\s | 匹配空白,即空格,tab键 |
\S | 匹配非空白 |
\w | 匹配非特殊字符,包括数字、字母、下画线、汉字 |
\W | 匹配特殊字符,即非字母、非数字、非汉字 |
2.2单字符规则使用
-
.匹配相对于,当需要匹配的字符在左边时,就是需要匹配的字符+后一个字符,如:匹配I love you (y.),运行结果就是:yo;在右边就匹配前一个字符。
-
\s\S:表示匹配一个空白字符后面紧跟着一个非空白字符,并且全局匹配;\S\s则表示前面非空白字符匹配一个紧跟着的空白字符。
-
[ ]里面匹配的单个字符,例如[abc],匹配a或b或c一个字符。在[]里面的大多数特殊字符在中括号表达式内出现时失去它们的意义。
-
()匹配一个子表达式,例如(abc),就只能匹配字符串abc。
2.3多字符匹配规则(注意都是匹配前面的字符)
代码 | 功能 |
---|---|
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,至少有一次 |
? | 匹配前一个字符出现1次或者0次 |
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
- *和+都是贪婪表达式,尽可能的匹配多的字符,在或+后面加一个?,将贪婪表达式转化为非贪婪表达式
2.4匹配分组
代码 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P<name) | 分组起别名 |
(?P=name) | 引用别名为name分组匹配到字符串 |
2.5字符匹配规则使用
-
^:从开始位置匹配,只能匹配一个字符
-
\b:匹配单词边界 ,确保字符串的完整性
-
[0-9]+:匹配多个数字(+匹配一个或多个)
-
abc 匹配字母 a b c 并以 a b c 结尾( 匹配字母abc并以abc结尾( 匹配字母abc并以abc结尾(为匹配输入字符串的结束位置)
-
[abc] :匹配a或b或c
-
[ ^abc ] :匹配除了a或b或c以外的任意字符
-
():用于分组和捕获子表达式。例如:([a-z]+)(\d+),两个子式
-
(? : ) : 用于分组但不捕获子表达式。(不捕获子表达式可以不用占用存储空间,仅仅是分组)
-
\ :转义字符,用于匹配特殊字符本身
-
. : 匹配任意字符(除了换行符)
-
| :用于指定多个模式。多个模式就是指不同的数字或者字符,匹配中|相当于或。从左到右匹配,返回第一个匹配到的值
案例
在写用户注册表单时,只允许用户包含字符、数字、下划线和连接符-,并设置用户名的长度,我们就可以使用以下正则表达式来设定。
1{3,15}$
以上表达式表示的是,以字母小写字母、数字、下划线、连接符-开头,3-15个字符长度的字符串表单。
2.6非打印字符
非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:
字符 | 描述 |
---|---|
\cx | 匹配由x指令的控制字符。例如,\cM 匹配一个 Control-M 或回车符。x的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
\f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。 |
\S | 匹配任何非空白字符。等价于 [^\f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
2.7特别字符描述
-
$ :匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则也匹配\n或 \r 。要匹配 $字符本身,请使用\ $。
-
():标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \ (和 \ )
-
*:匹配前面的子表达式零次或多次。要匹配 字符,请使用 \ *.
-
+:匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \ + 。
-
. :匹配除换行符 \n之外的任何单字符。要匹配.,请使用 \ . 。
注意
定位符和限定符不能一起用
\b单词边界就是匹配的字符与空格间的位置。以Chapter为例,例如\bCha表示匹配一个以Cha开头的单词,再例如ter\b就是表示匹配以ter作为结尾的单词。
\Bapt就是匹配不以apt作为开头或结尾的字符串
用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。其中?:是非捕获元之一,还有两个非捕获元是 P = P= P= 和?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
2.8?=、?<=、?!、?<!的使用区别
-
exp1( =exp2):查找 exp2 前面的exp1。
-
示例:/runoob(?=[\d+])/g
- 匹配数字前面的 runoob 字符串 ,如:123456runoob123runoob456
-
( ? <=exp2) exp1:查找 exp2 后面的 exp1。
-
示例 :/(?<=[0-9]+)runoob/g
- 匹配数字后面的 runoob 字符串,如:123456google123Funoob456
-
exp1(?!exp2):查找后面不是 exp2的exp1。
-
示例 : /runoob(?![0-9]+)/g
- 匹配 runnob,但后面不是数字 ,如:123456runoob-google123runoob456
-
(?<!exp2)exp1:查找前面不是 exp2 的 exp1。
案例
查找重复的单词:
var str = “Is is the cost of of gasoline going up up”;
var patt1 = /\b([a-z]+) \1\b/igm;
document.write(str.match(patt1));捕获的表达式,正如 [ a-z ]+ 指定的,包括一个或多个字母。正则表达式的第二部分是对以前捕获的子匹配项的引用,即,单词的第二个匹配项正好由括号表达式匹配。 \1 指定第一个子匹配项。
单词边界元字符确保只检测整个单词。否则,诸如"is issued"或"this is"之类的词组将不能正确地被此表达式识别。
正则表达式后面的全局标记 g指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。
表达式的结尾处的不区分大小写i标记指定不区分大小写。
多行标记 m指定换行符的两边可能出现潜在的匹配。\1表示一组内部关系,就是和前面第一个括号的一样,\2就是和第二个括号的内容一样,注意这里的匹配有局限性,必须是连续的并且要在\1的前面添加一个空格。
3.正则表达式常用修饰符
修饰符 | 含义 | 描述 |
---|---|---|
i | ignore-不区分大小写 | 将匹配设置为不区分大小写时,搜索a和A没有区别 |
g | global-q全局匹配 | 查找所有匹配项 |
m | multi line-多行匹配 | 使边界符^和$匹配每一行的开头和结尾,是多行,而不是整个字符串的开头和结尾 |
s | 特殊字符圆点.中包含换行符\n | 默认情况下的圆点.是匹配除换行符之外的任意字符的,加上s修饰符之后.中包含换行符\n |
4.运算符优先级
正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
运算符 | 描述 |
---|---|
\ | 转义符 |
(),(? : ),(?=),[ ] | 圆括号和方括号 |
*,+,?,{n},{n,},{n,m} | 限定符 |
^,$,\任何元字符,任何字符 | 定位点和序列(位置和顺序) |
| | 替换,"或"操作 |
结语:更详细的教程可参考菜鸟教程正则表达式部分
a-z0-9_- ↩︎