正则表达式初级
正则表达式图形化地址: https://regexper.com/#%2Fd%2F
正则表达式:
按照某种规则去匹配符合条件的字符串
RegExp:
字面量:var reg = /\bis\b/g;
构造函数:var reg = new RexExp('\\bis\\b', 'g');
通配符:
* 匹配任意字符
var reg = /\bis\b/g;
"he is a bog".replace(reg, "ss")
"he ss a bog"
修饰符:
g:global 全文搜索,不添加,默认搜索到第一个匹配停止
i:ignore case 忽略大小写,默认大小写敏感
m:multiple lines 多行搜索
元字符:不同的书写方式代表着不同的含义
原义文本字符: a b c
元字符: 是在正则表达式中有特殊含义的非字母字符
* + ? $ ^ . \ () {} []
字符类:
- 使用元字符[ ] 来构建一个简单的类
- 类就是把指符合某些特性的对象,一个泛指,而不是特指某个字符
- 表达式[abc] 把字符a或者b或者c归为一类,表达式可以匹配这类的字符
"a1b1c1".replace(/[abc]/,"x")
"x1b1c1"
"a1b1c1".replace(/[abc]/g,"x")
"x1x1x1"
字符类取反:
- 使用元字符 ^ 创建 反向类/负向类
- 反向类的意思是不属于某类的内容
- 表达式[^abc]表示 不是字符a 或 b 或 c 的内容
"a1b1c1".replace(/[^abc]/g,"x")
"axbxcx"
范围类:
[a-z] 表示从a到z的任意字符
闭区间,也就是包含a和z本身
"a1b2as3".replace(/[a-z]/g, "x")
"x1x2xx3"
"a1-b2-as3".replace(/[a-z-]/g, "x")
"x1xx2xxx3"
预定义类:
"ascdv12_A".replace(/\w/g, "x")
"xxxxxxxxx"
边界匹配字符:
^ 以XXX 开始
$ 以XXX结束
\b 单词边界
\B 非单词边界
"this is a body".replace(/\Bis\b/g,"x"); "thx is a body" "this is a body".replace(/\bis\b/g,"x"); "this x a body" "this is a body".replace(/\is/g,"x"); "thx x a body"
量词:
? 出现0次或者1次 (最多出现1次)
+ 出现一次或者多次 (至少出现1次)
* 出现0次或者多次 (任意次)
{n} 出现n次
{n,m} 出现n 到 m 次
{n,} 至少出现n次
最多10次 {0,10}
匹配出现20次的数值 /\d{20}/g
js 正则贪婪模式与非贪婪模式:
-贪婪模式竟可能多的匹配,知道匹配不成功为止
-- “12345678”.replace(/\d{3,6}/g, "X"); // "X78"
-非贪婪模式,如果有匹配到的将不在尝试继续匹配了,以此达到少的匹配。
-- 做法很简单,在量词后面加?就可以了
“12345678”.replace(/\d{3,6}?/g, "X"); // "x45678"
"12345678".replace(/\d{3,6}?/g, "X"); // "XX78"
分组:
匹配 body 连续出现3词的场景。 body{3} 这样只会匹配到y 出现的情况。并不可以使body单词出现3次。
使用()可以达到分组的功能,使量词作用于分组。 (body){3}
"a1b2c3d4".replace(/(\w\d){3}/g, "x") ; // "xd4"
或:使用 | 可以达到或的效果
反向引用:2025-12-25 => 12/25/2025 也叫捕获分组
"2025-12-25".replace(/\d{4}-\d{2}-\d{2}/g, "$1"); // "$1"
"2025-12-25".replace((\d{4})-(\d{2})-(\d{2})/g, "$1"); // "2025"
"2025-12-25".replace((\d{4})-(\d{3})-(\d{2})/g, "$2/$3/$1"); // "12/25/2025"
忽略分组:是需要在分组内加上 ?: 就可以了
前瞻后顾:
- 前瞻:正则表达式从文本头部向尾部开始解析,文本尾部方向,称之为 “前”,前瞻就是正则表达式匹配到规则的时候,向前检查是否断言。前瞻/后顾方向相反。
javascript 不支持后顾。
符合和不符合特定的断言称之为肯定/正向匹配和否定/负向匹配。
正向前瞻: /\w(?=\d)/g 只有正则部分会参与匹配。
"a1c2v44".replace(/\w(?=\d)/g, "x" ); // "x1x2xx4"
"a1c2v44".replace(/\w(?!\d)/g, "x"); // "axcxv4x"
正则表达式的对象属性:
g 是否全局匹配,默认false i 是否大小写敏感,默认false m 多行搜索,默认false
lastIndex 当前表达式匹配内容的最后一个字符的下一个位置。
source 正则表达式的文本字符串。
正则表达式的方法:
1. test RegExp.prototype.text(str) 用于匹配字符串参数中是否存在匹配正则表达式模式的字符串,存在返回true, 否则返回 false。
/\w/g.test("ab"); // true 第一次是true 第二次匹配为true 第三次为false。 是因为lastIndex 在影响。
解决方法: 如果用到 test 方法去掉 g 标识 或者每次实例化一个正则表达式 (/\w/g).test() 就可以了。
2. exec RegExp.prototype.exec 使用正则表达式模式对字符串执行搜索,并将更新全局RegExp对象的属性以反映匹配结果,如果没有匹配结果返回null,有的话返回一个结果数组。-index 声明匹配文本的第一个字符的位置 -input 存放被检索的字符串(string)
非全局匹配与全局匹配
* 返回数组 第一项是与正则表达式相匹配的文本,第二项是与正则表达式第一个子表达式相匹配的文本(如果有的话),第三项是与正则表达式第二个子表达式相匹配的文本。(如果有的话)。。。以此类推
全局匹配下 lastIndex 生效
非全局匹配下 lastIndex 不生效
字符串对象的方法:
1. String.prototype.search(reg) 匹配对应字符串是否存在,有的话返回对应的下标,没有的话返回-1,它会忽略g标识,不执行全局匹配,总是从字符串的开始进行检索。
2. String.prototype.match(reg) 检索字符串,以找到一个或者多个regExp相匹配的文本。对是否具有g标识有很大的影响。
非全局调用
* 返回数组第一个元素是匹配的文本,而其他元素存放的是与正则表达式的子表达式相匹配的文本。除了常规数组元素之外,还有2个对象的属性,
- index 声明匹配文本的起始字符在字符串的位置
- input 声明对stringObj的引用
全局调用
* 全局进行检索,找到字符串中所有匹配的字符串,没有匹配的返回null, 找到一个或者多个子串的话,返回一个数组。
数组元素中存放的是所有匹配项的匹配子项,没有index 和 input 属性。
3. String.prototype.split(reg) 把字符串分割成字符数组。也可以通过传入正则表达式来进行转换。
“abcd”.split(","); // [a,b,c,d] 其实在做转化 “abcd”.split(/,/); // [a,b,c,d]
"a1b2c3d4".split(/\d/); // [a,b,c,d]
4. String.prototype.replace(reg, str) 传两个参数,第一个要替换的项,第二个是要替换成什么项。
String.prototype.replace(reg, function) function会在每次匹配替换的时候会被调用,它有4个参数。
- 匹配字符串 -- 正则表达式的分组内容,没有分组则没有该项 ---匹配项在该字符换的index ----原字符串