在计算机语言中,正则表达模式匹配是非常高效的字符串处理方式。我们在进行字符串处理的时候,比如表单校验、url参数获取、文本预编译处理,多端跨端转译等等,都少不了跟正则表达式打交道。但由于正则表达的语法规则比较抽象,如果平常不经常接触,一旦要用,就得好一番查找资料。但是网上的资料很多都太零散,为方便以后高效查看,略系统地整理如下。
一、什么是正则表达式
正则表达式(Regular Expression),是一串特殊的字符串,用来描述一组字符串的规律和规则。正则表达式可用于验证、检索、匹配、替换文本字符串。
二、正则表达式的简要发展史
- 在对人类神经系统的早期研究中,科学家 Warren McCulloch 和 Walter Pitts 研究出了一种用数学方式来描述神经网络的新方法。
- 1951年, 数学科学家 Stephen Kleene,在他的《神经网事件的表示法》的论文中,利用称之为正则集合的数学符号来描述上述模型,引入了正则表达式的概念。
- 自此以后,正则表达式被广泛地应用到各种 UNIX 或类似于 UNIX 的工具中。
- 正则表达式在各种计算机语言和应用领域得到了广大的应用和发展。
三、正则引擎
正则引擎可以让正则表达式得以工作。主流的正则引擎分为3类:
- DFA:确定型有穷自动机(Deterministic finite automaton, DFA)
- 传统型NFA:非确定型有穷自动机(Non-deterministic finite automaton, NFA)
- POSIX NFA:由于DFA和传统型NFA这两种引擎产生了很多变体,为了规避不必要变体的继续产生,出台了POSIX
四 、正则表达式语法
正则表达式语法格式:1
/pattern/flags
- pattern部分由普通字符以及特殊字符(也被称为”元字符”)组成。
- flags部分非必填
4.1 普通字符
没有显式指定为元字符的所有可打印和不可打印字符。包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
4.2 特殊字符(元字符)
\
1 | 依照下列规则匹配: |
^
1 | 匹配输入的开始。如果多行标志被设置为 true,那么也匹配换行符后紧跟的位置。 |
$
1 | 匹配输入的结束。如果多行标志被设置为 true,那么也匹配换行符前的位置。 |
*
1 | 匹配前一个表达式 0 次或多次。等价于 {0,}。 |
+
1 | 匹配前面一个表达式 1 次或者多次。等价于 {1,}。 |
?
1 | 匹配前面一个表达式 0 次或者 1 次。等价于 {0,1}。 |
.
1 | (小数点)默认匹配除换行符之外的任何单个字符。 |
(x)
1 | 像下面的例子展示的那样,它会匹配 'x' 并且记住匹配项。其中括号被称为捕获括号。 |
(?:x)
1 | 匹配 'x' 但是不记住匹配项。这种括号叫作非捕获括号,使得你能够定义与正则表达式运算符一起使用的子表达式。 |
x(?=y)
1 | 匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言。 |
(?<=y)x
1 | 匹配'x'仅当'x'前面是'y'.这种叫做后行断言。 |
x(?!y)
1 | 仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找。 |
(?<!y)x
1 | 仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找。 |
x|y
1 | 匹配‘x’或者‘y’。 |
{n}
1 | n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。 |
{n,}
1 | n 是一个正整数,匹配前一个字符至少出现了 n 次。 |
{n,m}
1 | n 和 m 都是整数。匹配前面的字符至少 n 次,最多 m 次。如果 n 或者 m 的值是 0,这个值被忽略。 |
[xyz]
1 | 一个字符集合。匹配方括号中的任意字符,包括转义序列。 |
[^xyz]
1 | 一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。 |
[\b]
1 | 匹配一个退格 (U+0008)。(不要和\b混淆了。) |
\b
1 | 匹配一个词的边界。一个词的边界就是一个词不被另外一个“字”字符跟随的位置或者前面跟其他“字”字符的位置,例如在字母和空格之间。注意,匹配中不包括匹配的字边界。换句话说,一个匹配的词的边界的内容的长度是 0。(不要和 [\b] 混淆了) |
\B
1 | 匹配一个非单词边界。匹配如下几种情况: |
\cX
1 | 当 X 是处于 A 到 Z 之间的字符的时候,匹配字符串中的一个控制符。 |
\d
1 | 匹配一个数字。等价于 [0-9]。 |
\D
1 | 匹配一个非数字字符。等价于 [^0-9]。 |
\f
1 | 匹配一个换页符 (U+000C)。 |
\n
1 | 匹配一个换行符 (U+000A)。 |
\r
1 | 匹配一个回车符 (U+000D)。 |
\s
1 | 匹配一个空白字符,包括空格、制表符、换页符和换行符。等价于 [\f\n\r\t\v\u0020\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。 |
\S
1 | 匹配一个非空白字符。等价于 [^\f\n\r\t\v\u0020\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。 |
\t
1 | 匹配一个水平制表符 (U+0009)。 |
\v
1 | 匹配一个垂直制表符 (U+000B)。 |
\w
1 | 匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_]。 |
\W
1 | 匹配一个非单字字符。等价于 [^A-Za-z0-9_]。 |
\n
1 | 在正则表达式中,它返回最后的第 n 个子捕获匹配的子字符串 (捕获的数目以左括号计数)。 |
\0
1 | 匹配 NULL(U+0000)字符,不要在这后面跟其他小数,因为 \0<digits> 是一个八进制转义序列。 |
\xhh
1 | 匹配一个两位十六进制数(\x00-\xFF)表示的字符。 |
\uhhhh
1 | 匹配一个四位十六进制数表示的 UTF-16 代码单元。 |
\u{hhhh}或\u{hhhhh}
1 | (仅当设置了 u 标志时)匹配一个十六进制数表示的 Unicode 字符。 |
4.3 flags
正则表达式有六个可选参数 (flags) 允许全局和不分大小写搜索等。这些参数既可以单独使用也能以任意顺序一起使用,并且被包含在正则表达式实例中。1
2
3
4
5
6g 全局搜索。
i 不区分大小写搜索。
m 多行搜索。
s 允许 . 匹配换行符。
u 使用 unicode 码的模式进行匹配。
y 执行“粘性 (sticky)”搜索,匹配从目标字符串的当前位置开始。
JavaScript中正则表达式的使用方法
exec
在字符串中执行查找匹配,返回一个数组(未匹配到则返回 null)。【RegExp 方法】1
2var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
1 | var myRe = new RegExp("d(b+)d", "g"); |
test
在字符串中测试是否匹配,返回 true 或 false。【RegExp 方法】1
2
3var str='abcdef';
var re=/b/;
alert(re.test(str));
match
在字符串中执行查找匹配,返回一个数组,在未匹配到时会返回 null。【String 方法】1
2
3
4
5
6var re = /\w+\s/g;
var str = "fee fi fo fum";
var myArray = str.match(re);
console.log(myArray);
// ["fee ", "fi ", "fo "]
matchAll
在字符串中执行查找所有匹配,返回一个迭代器(iterator)。【String 方法】1
2
3
4
5
6
7
8
9const str = 'hello javascript hello css';
console.log(...str.matchAll(/hello/g));
// [0: "hello", groups: undefined, index: 0, input: "hello javascript hello css"]
// [0: "hello", groups: undefined, index: 17, input: "hello javascript hello css"]
// 0: "hello" 匹配的字符串,如果有使用分组会在后面依次列出来
// groups: undefined 没有使用命名捕获组会返回undefined,否则会返回包含命名捕获组的对象
// index: 0 匹配的结果在当前字符串位置开始的索引
// input: "hello javascript hello css" 当前字符串
search
在字符串中测试匹配,返回匹配到的位置索引,或者在失败时返回 -1。【String 方法】1
2
3
4
5
6
7
8var str="abcdef";
var re=/b/;
alert(str.search(re));
//返回1
var re=/w/;
//返回-1
var re=/B/;
//返回-1
replace
在字符串中执行查找匹配,并且使用替换字符串替换掉匹配到的子字符串。【String 方法】1
2
3
4var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);
split
使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中。【String 方法】1
2
3var str="How are you doing today?";
var n=str.split(/a/);
// 返回['How ', 're you doing tod', 'y?']