正则表达式学习
点击查看参考教程
参考内容 | 参考链接 |
---|---|
正则表达式学习 | 正则表达式 |
特殊字符() | 正则表达式括号的作用 |
单词边界 | 正则表达式单词边界和非单词边界 |
正则表达式的创建
两种方式进行创建:
使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示:
var re = /\d/g; |
调用RegExp
对象的构造函数,如下所示:
var re = new RegExp("\\d", "g"); |
转移字符\
要进行转义,写成\\
JS 中正则表达式的匹配
字符串的方法match
进行匹配:
let str = "abca"; |
字符串的方法match
进行匹配:
let str = "abca"; |
正则表达式标志
标志 | 描述 |
---|---|
g |
全局搜索,所有正则表达式都有一个 lastIndex 属性,用于记录上一次匹配结束位置,如果没有设置全局匹配,那么 lastIndex 始终为 0 |
i |
不区分大小写搜索 |
m |
多行搜索,没有 m 则匹配整个文本;只会影响到 ^ 和 $ |
s |
允许 . 匹配换行符 |
u |
使用 unicode 码的模式进行匹配 |
y |
执行“粘性(sticky )”搜索,匹配从目标字符串的当前位置开始 |
特殊字符
符号^
匹配输入开始。如果多行搜索标志被设置为 true,那么也匹配换行符后的位置。
无多行搜索
let str1 = "abc"; |
正则表达式会匹配abc
开头的a
有多行搜索
let str = `abcabc |
注意多行文本使用的不是单引号而是反单引号
正则表达式会匹配字符串a
开头,因为开启全局搜索g
和多行搜索m
,所以会对每一行进行匹配,所以会匹配文本每行开头的a
。
如果没有开启多行搜索m
那么就会把文本当成一行进行匹配,所以只会匹配到开头的的一个a
。
符号$
匹配输入的结束。如果多行标志被设置为 true,那么也匹配换行符前的位置。
let str1 = "bca"; |
正则表达式会匹配bca
结尾的a
let str = `bcabca |
注意多行文本使用的不是单引号而是反单引号
正则表达式会匹配字符串 a
结尾,有全局搜索 g
和多行搜索 m
,会匹配每行开头的 a
。
符号{}
类型 | 含义 |
---|---|
{n} |
n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。 |
{n,} |
n 是一个正整数,匹配前一个字符至少出现了 n 次。 |
{n,m} |
n 和 m 都是整数。匹配前面的字符至少 n 次,最多 m 次。如果 n 或者 m 的值是 0, 这个值被忽略。 |
/a{2}/
不会匹配“candy”中的’a’,但是会匹配“caandy”中所有的 a,以及“caaandy”中的前两个’a’。
/a{2,}/
匹配 “aa”, “aaaa” 和 “aaaaa” 但是不匹配 “a”。
/a{1, 3}/
匹配“candy”中的 a,匹配“caandy”中的前两个 a,也匹配“caaaaaaandy”中的前三个 a。
符号*
匹配前一个表达式 0 次或多次,等价于 {0,}
。
/bo*/
会匹配 “A ghost boooooed” 中的 ‘booooo’ 和 “A bird warbled” 中的 ‘b’,但是在 “A goat grunted” 中不会匹配任何内容。
符号+
匹配前面一个表达式 1 次或者多次,等价于 {1,}
。
/a+/
会匹配 “candy” 中的 ‘a’ 和 “caaaaaaandy” 中所有的 ‘a’,但是在 “cndy” 中不会匹配任何内容。
符号.
匹配除换行符之外的任何单个字符。如果设置标志 s
为 true 的话,也可以匹配换行符
/.n/
将会匹配 “nay, an apple is on the tree” 中的 ‘an’ 和 ‘on’
符号|
x|y
匹配‘x’或者‘y’。
/green|red/
匹配“green apple”中的‘green’和“red apple”中的‘red’
符号()
类型 | 含义 |
---|---|
(X) |
匹配 ‘x’ 并且记住匹配项。其中括号被称为捕获括号。 |
(?:x) |
匹配 ‘x’ 但是不记住匹配项。这种括号叫作非捕获括号。 |
x(?=y) |
匹配’x’当且仅当’x’后面是’y’,这种叫做先行断言。 |
(?<=y)x |
匹配’x’当且仅当’x’前面是’y’,这种叫做后行断言。 |
x(?!y) |
当且仅当’x’后面不是’y’时匹配’x’,这被称为正向否定查找。 |
(?<!y)x |
当且仅当’x’前面不是’y’时匹配’x’,这被称为反向否定查找。 |
1.其中 (x)
的用法较多,分为三个部分
-
如果现在需要匹配连续的两个及以上的字符时,就需要使用
()
let str = "ababa abbb ababab";
var re = /(ab)+/g;
console.log(str.match(re)); //输出['abab', 'ab', 'ababab'] -
在分支结构中使用
(x|y)
var re = /^hello (world|this is my blog)$/;
console.log(re.test("hello world")); //true
console.log(re.test("hello this is my blog")); //true如果没有添加括号可能会产生歧义,那么对于“hello world”、“this is my blog”、“hello this is my blog”、“hello world is my blog”都可以匹配成功
括号一个重要的功能就是捕获功能,它会记住捕获的字符串
var regex = /(\d{4})-(\d{2})-(\d{2})/; |
执行 exec
输出的结果第一个元素是整体匹配的结果,然后是各个分组(括号里)匹配的内容,然后是匹配下标,最后是输入的文本。通过构造函数的全局属性 $1
至 $9
可以获取详细的值。
如果想把 yyyy-mm-dd
格式,替换成 mm/dd/yyyy
var re = /(\d{4})-(\d{2})-(\d{2})/; |
通过 replace 函数进行替换,通过 $1
、 $2
、 $3
来进行替换
如果要写一个正则支持匹配如下三种格式
2016-06-12
2016/06/12
2016.06.12
var re = /\d{4}(-|\/|\.)\d{2}\1\d{2}/; |
通过这个正则表达式即可匹配成功,因为括号 (-|\/|\.)
会将匹配的内容记住,其中 \1
表示第一个括号匹配的字符串。
那么 \n
(n 是整数)就代表第 n 个括号匹配的内容。
如果有括号嵌套,则以左括号为准判断第几个括号
var re = /^((\d)(\d(\d)))\1\2\3\4$/; |
2.(?:x)
相比于 (x)
没有的捕获的功能,相当于一个原始的括号的功能
var re = /(?:ab)+/g; |
3.x(?=y)
/Jack(?=Sprat)/
会匹配到’Jack’仅当它后面跟着’Sprat’。/Jack(?=Sprat|Frost)/
匹配‘Jack’仅当它后面跟着’Sprat’或者是‘Frost’。但是‘Sprat’和‘Frost’都不是匹配结果的一部分。
4.(?<=y)x
/(?<=Jack)Sprat/
会匹配到’ Sprat ‘仅仅当它前面是’ Jack '。/(?<=Jack|Tom)Sprat/
匹配‘ Sprat ’仅仅当它前面是’Jack’或者是‘Tom’。但是‘Jack’和‘Tom’都不是匹配结果的一部分。
5.x(?!y)
仅当这个数字后面没有跟小数点的时候,/\d+(?!\.)/
匹配一个数字。正则表达式 /\d+(?!\.)/.exec("3.141")
匹配‘141’而不是‘3.141’
6.(?<!y)x
仅当这个数字前面没有负号的时候,/(?<!-)\d+/
匹配一个数字。/(?<!-)\d+/.exec('3')
匹配到 “3”。/(?<!-)\d+/.exec('-3')
因为这个数字前有负号,所以没有匹配到。
符号?
匹配前面一个表达式 0 次或者 1 次,等价于 {0,1}
。如果 ?
紧跟任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪模式(匹配尽量少的字符)
-
/e?le?/
匹配 “angel” 中的 ‘el’、“angle” 中的 ‘le’ 以及 "oslo’ 中的 ‘l’。 -
贪婪模式
如果想捕获一串字符串中的数字(可以
\d+
匹配数字),通过如下方法let str = "abc1234567abc";
var re = /.*(\d+).*$/;
console.log(str.match(re));
//['abc123456abc', '7', index: 0, input: 'hello 1234567 world']贪婪模式下会尽可能多的匹配,
.*
可以匹配任意个非换行字符,所以.*
会尽可能多的匹配字符,在贪婪模式下,.*
会匹配“abc123456”,留给捕获符号中的\d+
能够捕获的就是7
,这一个字符 -
非贪婪模式
同样的将上面的
.*
改为非贪婪模式let str = "abc1234567abc";
var re = /.*?(\d+).*$/;
console.log(str.match(re));
//['abc123456abc', '1234567', index: 0, input: 'hello 1234567 world']贪婪模式下会尽可能少的匹配字符,在碰到数字字符后会交给
\d+
,所以可以捕获到“1234567”
符号[]
类型 | 含义 |
---|---|
[xyz] |
一个字符集合。匹配方括号中的任意字符,包括转义序列。你可以使用破折号(-)来指定一个字符范围。 |
[^xyz] |
一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。你可以使用破折号(-)来指定一个字符范围。 |
[\b] |
匹配转义字符\b 本身(匹配退格键\u0008) |
正则表达式中,有些标点符号需要进行转义,如果不记得可以给每一个都加上转义符号“\”
-
/[abcd]/
和/[a-d]/
是一样的。他们都匹配"brisket"中的‘b’。/[a-z.]+/
与字符串“test.i.ng”匹配。console.log("brisket".match(/[abc]/)); //['b', index: 0, input: 'brisket']
console.log("test.i.ng".match(/[a-z.]+/)); //['test.i.ng', index: 0, input: 'test.i.ng'] -
/[^abc]/
和/[^a-c]/
是一样的。他们匹配"brisket"中的‘r’,也匹配“chop”中的‘h’。console.log("brisket".match(/[^a-c]/)); //['r', index: 1, input: 'brisket]
符号\w
和\W
\w
:匹配一个单字字符(字母、数字或者下划线),等价于 [A-Za-z0-9_]
。
\W
:匹配一个非单字字符,等价于 [^A-Za-z0-9_]
。
符号\b
匹配一个词的边界。
\b
它并不匹配字符,类似于 ^
和 $
起到的只是识别的作用,检查是否为边界
let str = `abc**abc |
非边界字符包括:大写和小写的罗马字母,十进制数字和下划线字符。对于其他的字符都会被视为断词,即会被视为边界。
在上面的匹配中“**”和换行符均会识别为边界,单词的前后均没有跟随的字符也被视为边界。如果以 |
符号当做边界符号的化,那么上面的 str 就可以划分为 |abc|**|abc|\n|123|
其他例子:
/\bm/
匹配“moon”中的‘m’;
/oo\b/
并不匹配"moon"中的’oo’,因为’oo’被一个“字”字符’n’紧跟着。
/oon\b/
匹配"moon"中的’oon’,因为’oon’是这个字符串的结束部分。这样他没有被一个“字”字符紧跟着。
符号\B
匹配一个非单词边界。
和单词边界一样单词以 |
为边界字符串可以看成 |abc|**|abc|\n|123|
,非单词边界就是将单词边界以外的地方当做边界,得到 a|b|c*|*a|b|c\n1|2|3
,然后匹配边界内的内容是否符合要求
let str = `abc**abc |
正则表达式匹配所有非字符串边界中的字符,包括换行符,即要匹配的有“b”、“c*”、“*a”、“b”、“c\n1”、“2”这些字符
其他案例:
/\B../
匹配"noonday"中的’oo’, 而 /y\B../
匹配"possibly yesterday"中的’yes‘
符号\cX
当 X 是处于 A 到 Z 之间的字符的时候,匹配字符串中的一个控制符。
例如,/\cM/
匹配字符串中的 control-M (U+000D),其他可查看控制字符
console.log(/\cM/.exec("123\u000D123")); //['\r', index: 3, input: '123\r123'] |
符号\d
和\D
\d
:匹配一个数字,等价于[0-9]
。
\D
:匹配一个非数字字符,等价于[^0-9]
。
其他字符
符号 | 含义 |
---|---|
\f |
匹配一个换页符 (U+000C) |
\n |
匹配一个换行符 (U+000A) |
\r |
匹配一个回车符 (U+000D) |
\s |
匹配一个空白字符,包括空格、制表符、换页符和换行符。等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] |
\S |
匹配一个非空白字符。等价于 [^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] |
\t |
匹配一个水平制表符 (U+0009) |
\v |
匹配一个垂直制表符 (U+000B) |
\0 |
匹配 NULL(U+0000)字符 |
\xhh |
匹配一个两位十六进制数(\x00-\xFF)表示的字符 |
\uhhhh |
匹配一个两位十六进制数(\x00-\xFF)表示的字符 |
\u{hhhh} 或\u{hhhhh} |
(仅当设置了 u 标志时)匹配一个十六进制数表示的 Unicode 字符。 |