前言
正则表达式在编码中会经常使用到,但是平时只是需要的时候就去看看。往往看到那些元字符、量词就直接跳过,直接百度了,一直没有很深入的去了解,现在有时间就简单总结一下。
基本概念
正则表达式是一种文本模式,包括普通字符
(例如,a 到 z 之间的字母)和特殊字符
(称为“元字符”)。模式描述在搜索文本时要匹配的一个或多个字符串。
正则使用场景:
1. 检查文本中是否含有指定的特征词
2. 找出文中匹配特征词的位置
3. 从文本中提取信息,比如:字符串的子串
4. 修改文本
元字符
元字符是在正则表达式中你有特殊含义的非字母字符。元字符必须转义
( ) [ ] { } ^ $ | ? * + .
修饰符
- g: global,全文搜索,如果不添加,搜索到第一个匹配就停止。
- i: ignore case,忽略大小写,默认大小写敏感。
- m: mutiple lines,多行搜索
字符类匹配
字符 | 匹配 |
---|---|
[...] | 匹配方括号内的任意字符 例如[abcd]
|
[^ x ] | 匹配除了x以外的任意字符 例如 [^abcd] 匹配除了abcd以外的任意字符 |
. | 匹配除了换行符 |
\s | 匹配任意的空白符 |
\S | 匹配任意不是空白符的字符 |
\w | 匹配字母或者数字、下划线、汉字 等价于[a-zA-Z0-9]
|
\W | 匹配不是字母或者数字、下划线、汉字 |
\d | 匹配任意数字 |
\D | 匹配任意非数字的字符 |
\b | 匹配单词的开始或者结束的位置 |
重复字符匹配
字符 | 匹配 |
---|---|
{n,m} | 匹配前一项至少n次,但不能超过m次 |
{n,} | 匹配前一项n次或更多次 |
{n} | 匹配前一项n次 |
? | 匹配前一项0次或者1次,也就是说前一项是可选的,等价于{0,1} |
+ | 匹配前一项1次或多次,等价于{1,} |
* | 匹配前一项0次或多次,等价于{0,} |
字符类:锚字符 匹配
元字符/元符号 | 匹配 |
---|---|
$ | 匹配字符串的结尾,在多行检索中,匹配一行的结尾 |
^ | 匹配字符串的开头,在多行检索中,匹配一行的开头 |
A | 只有匹配字符串开始处 |
b | 匹配单词边界,词在 []内时无效 |
\B | 匹配非单词边界 |
\G | 匹配当前搜索的开始位置 |
\Z | 匹配字符串结束处或行尾 |
\z | 只匹配字符串结束处 |
字符类:记录字符 匹配
元字符/元符号 | 匹配情况 |
---|---|
(string) | 用于反向引用的分组 |
1 或$1 | 匹配第一个分组中的内容 |
2 或$2 | 匹配第二个分组中的内容 |
3 或$3 | 匹配第三个分组中的内容 |
正则表达式修饰符
字符 含义
i 执行不区分大小写的匹配
g 执行一个全局匹配,即找到所有匹配而非一次匹配
m 多行匹配模式,^匹配一行的开头和字符串开头,$匹配行的结束和字符串的结尾
构造方式
1.字面量
var pattern = /\bis\b/g;
eg:
var reg1=/hello world (\w*)/gi;
2.构造函数
var pattern = new RegExp('\\bis\\b', 'g');
new RegExp("正则表格式字符串",正则表达式修饰符);
注意⚠️: 因为构造函数中使用的是字符串,由于字符串转义问题,"\\"代表"\"。
RegExp对象方法
RegExp对象给我们提供了三种方法供我们使用,分别是test()、exec()和compile()。下面具体说一下这三个方法的用处。
1.test()
检索字符串中指定的值。返回 true 或 false。这个是我们平时最常用的方法。
var reg=/hello \w{3,12}/;
alert(reg.test('hello js'));//false
alert(reg.test('hello javascript'));//true
2.exec()
检索字符串中指定的值。匹配成功返回一个数组,匹配失败返回null。
var reg=/hello/;
console.log(reg.exec('hellojs'));//['hello']
console.log(reg.exec('javascript'));//null
3.compile()
compile() 方法用于改变 RegExp。
compile() 既可以改变检索模式,也可以添加或删除第二个参数。
var reg=/hello/;
console.log(reg.exec('hellojs'));//['hello']
reg.compile('Hello');
console.log(reg.exec('hellojs'));//null
reg.compile('Hello','i');
console.log(reg.exec('hellojs'));//['hello']
举几个例子
1.匹配下面的电话号码:
1. (010)88886666
2. 022-22334455
3. 02912345678
/\(?0\d{2}[\)-]?\d{8}/;
验证如下
var regex = /\(?0\d{2}[\)-]?\d{8}/;
regex.test(" 02912345678")
regex.test(" 022-22334455")
regex.test("(010)88886666")
true
2.匹配ip地址
IP地址格式可表示为:XXX.XXX.XXX.XXX,XXX取值范围是0-255,前三段加一个.重复了三次,在与最后一段合并及组成IP地址的完整格式。
最简单的写法 /([0-9]{1,3}\.){3}[0-9]{1,3}/
但是这样会匹配到很多无效的ip xxx的范围超过255.
所以对这个写法进行改进
- 当xxx只有一位的时候 取值的范围是[1-9] 可以表示为
[1-9]
- 当xxx为两位时 取值范围为[0-99] 可以表示为
[1-9]\d
- 当xxx为三位数时最高位取值为1 取值范围为[100 - 199] 可以表示为
[1]\d{2}
最高位取值为2 第二位不超过5时 取值范围为[200 - 249] 可以表示为2[0-4]\d
最高位取值为2,十位取值5,个位取值0-5 取值范围为 [250 - 255] 表示为25[0-5]
将这三种情况合并可以表示(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))
整个ip的正则可以表示为 ((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))
但是这还存在问题 现在只要字符串中有一部分能够通过校验test就会返回true 例如2313.2.3.4。
var regex = /((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))/;
regex.test("3424.2.3.2");
true
所以还要对正则的启始位置进行限制
var regex = /^((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))$/;
regex.test("3424.2.3.2");
false
第一部分简单回顾了正则表达式的基础知识,下一部分重点介绍正则的分组语法 和 常用方法
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。