JavaScript正则表达式使用及常用示例

# 正则表达式

正则表达式是用于匹配字符串中字符组合的模式。正则表达式的强大与灵活不必多说,在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、matchAll、replace、search 和 split 方法。

# 创建正则

js中可以使用以下两种方法构建一个正则表达式:

使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示:

 const regExp = /ab+c/;

脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。

调用RegExp对象的构造函数,如下所示:

 const regExp = new RegExp("ab+c");

在脚本运行过程中,用构造函数创建的正则表达式会被编译。如果正则表达式将会改变,或者它将会从用户输入等来源中动态地产生,就需要使用构造函数来创建正则表达式。

JavaScript的正则表达式还有几个特殊的标志,最常用的是g,表示全局匹配:

const r1 = /test/g;
// 等价于:
const r2 = new RegExp('test', 'g');

除此之外还有gmiyus

标示 缩写 说明
g global 全局匹配,匹配到第一个之后继续搜索全部
i insensitive 忽略大小写
m multiple line 多行模式
s single line 单行模式
u unicode 开启完整的 unicode 支持
y sticky 粘滞模式

这个示例^[\u4E00-\u9FA5A-Za-z0-9_]+$ 含义为匹配中文、英文、数字包括下划线

// 字面量形式可直接··//···包裹起来
const reg = /^[\u4E00-\u9FA5A-Za-z0-9_]+$/ 
// new 对象的时候,因为字符串的转义问题,字符串的两个\\实际上是一个\
const reg2 = new RegExp('^[\\u4E00-\\u9FA5A-Za-z0-9_]+$')

# 正则方法

# test

test方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。

/^hello/.test('hello'); // true 以hello开头
/123hello/.test('hello'); // true 包含hello
/h1ello/.test('hello'); // false 

注意

如果正则表达式设置了全局标志,test() 的执行会改变正则表达式,lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串,(exec() 同样改变正则本身的 lastIndex属性值).

let reg = /hello/g;

// lastIndex = 0
reg.lastIndex === 0 // true
reg.test('hello'); // true

// lastIndex = 5
reg.lastIndex === 5 // true
reg.test('hello'); // false

# match

一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。

'1,23,4akd,121'.match(/\d+/g); // ["1", "23", "4", "121"] 全局模式下会匹配出所有满足的元素
'1,23,4akd,121'.match(/\d+/); // ["1", index: 0, input: "1,23,4akd,121", groups: undefined] 

# matchAll

一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。

let it = '1,23,4akd,121'.matchAll(/\d+/g);
it.next(); // {value: ["1", index: 0, input: "1,23,4akd,121", groups: undefined], done: false}
it.next(); // {value: ["23", index: 2, input: "1,23,4akd,121", groups: undefined], done: false}

# replace

一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。

"Mr Blue has a blue house and a blue car".replace('b','121'); // "Mr Blue has a 121lue house and a blue car"
"Mr Blue has a blue house and a blue car".replace(/b/g,'121'); // "Mr Blue has a 121lue house and a 121lue car"
"Mr Blue has a blue house and a blue car".replace(/b/gi,'121'); // "Mr 121lue has a 121lue house and a 121lue car"

一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。

"Mr. Blue has a blue house".search('Mr'); // 0
"Mr. Blue has a blue house".search('mr'); // -1
"Mr. Blue has a blue house".search(/mr/i); // 0

# split

一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。

"How are you doing today?".split(''); // ["H", "o", "w", " ", "a", "r", "e", " ", "y", "o", "u", " ", "d", "o", "i", "n", "g", " ", "t", "o", "d", "a", "y", "?"]
"How are you doing today?".split(); // ["How are you doing today?"]
"How are you doing today?".split(' '); //  ["How", "are", "you", "doing", "today?"]
"How are you doing today?".split('o'); // ["H", "w are y", "u d", "ing t", "day?"]
"How are you doing today?".split(' ',3); // ["How", "are", "you"]
"Ho1w are you d1oing t3oday?".split(/\d/) // ["Ho", "w are you d", "oing t", "oday?"]

# exec

一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。

注意

在设置了 global 或 sticky 标志位的情况下(如 /foo/g or /foo/y),JavaScript RegExp 对象是有状态的。他们会将上次成功匹配后的位置记录在 lastIndex 属性中。使用此特性,exec() 可用来对单个字符串中的多次匹配结果进行逐条的遍历(包括捕获到的匹配),而相比之下, String.prototype.match() 只会返回匹配到的结果。

如果你只是为了判断是否匹配(true或 false),可以使用 RegExp.test() 方法,或者 String.search() 方法。

const reg = /a/g;
const str = 'abc_abc_abc'

const r1 = reg.exec(str);
r1 // ["a"]
r1.index // 0
reg.lastIndex // 1

const r2 = reg.exec(str);
r2 // ["a"]
r2.index // 4
reg.lastIndex // 5

const r3 = reg.exec(str);
r3 // ["a"]
r3.index // 8
reg.lastIndex // 9

const r4 = reg.exec(str);
r4 // null
reg.lastIndex // 0
const reg = /a/g;
const str = 'abc_abc_abc'

while(true) {
  let match = reg.exec(str);
  if (!match) break;
  console.log('#' + match.index + ':' + match[0]);
}
// #0:a
// #4:a
// #8:a

# 常用正则表达式

# 数字

/^\d+$/.test(123); // 正整数
/^-\d+$/.test(-123); // 负整数
/^-?\d+$/.test(-123); // 正负整数

/^\d*\.?\d+$/.test(123.2); // 小数正数
/^-\d*\.?\d+$/.test(-123.1); // 小数负数
/^-?\d*\.?\d+$/.test(-12.12); // 正负小数

/^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$/.test(123.12);// 非负浮点数
/^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$/.test(123.12);// 非正浮点数

# Email

/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test('123@123.com') // true

# Url

/^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test('https://www.nowhere.ink/') // true

# 十六进制颜色正则

/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/.test('#f8f8f8')

# 中文正则

/[\u4E00-\u9FA5]/.test('速度快');  // true 包含中文 
/^[\u4e00-\u9fa5]{0,}$/.test('sk说看看'); // false 全部中文

# 字母

/^[A-Z]+$/.test('AA'); // 大写字母
/^[a-z]+$/.test('AA'); // 小写字母
/^[A-Za-z0-9]+$/.test('A1aA'); // 大小写字母数字

# 其他

/^.{3,20}$/.test('1233'); // 长度为3-20的所有字符
最近更新
01
echarts扇形模拟镜头焦距与可视化角度示意图
03-10
02
vite插件钩子
03-02
03
vite的依赖预构建
02-13
更多文章>