JS-20-RegExp正则表达式

一、正则表达式的定义

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它"匹配"了,否则,该字符串就是不合法的。

比如,我们判断一个字符串是否是合法的Email的方法是:

  1. 创建一个匹配Email的正则表达式;

  2. 用该正则表达式去匹配用户的输入来判断是否合法。

因为正则表达式也是用字符串表示的,所以,我们要首先了解如何用字符来描述字符。

二、正则表达式的语法

2-1、精确匹配

在正则表达式中,如果直接给出字符,就是精确匹配。

  • \d可以匹配一个数字;
  • \w可以匹配一个字母或数字;
  • . 可以匹配任意字符;
  • \s可以匹配一个空格(也包括Tab等空白符)
  • A|B可以匹配A或B
  • ^表示行的开头,^\d表示必须以数字开头。
  • $表示行的结束,\d$表示必须以数字结束。

示例:

1、'00\d'可以匹配'007',但无法匹配'00A';

2、'\d\d\d'可以匹配'010';

3、'\w\w'可以匹配'js',也可以匹配'2j';

4、'js.'可以匹配'jsp''jss''js!'等等。

2-2、匹配变长的字符

  • *表示任意个字符(包括0个);
  • +表示至少一个字符;
  • ?表示0个或1个字符;
  • {n}表示n个字符,用{n,m}表示n-m个字符;

示例:\d{3}\s+\d{3,8},解读如下:

1、\d{3}表示匹配3个数字,例如'010'

2、\s+表示至少有一个空格,例如匹配' ''\t\t'等;

3、\d{3,8}表示3-8个数字,例如'1234567'

综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。

2-3、转义字符

示例:要匹配'010-12345'这样的号码,由于'-'是特殊字符,在正则表达式中,要用'\'转义,所以,上面的正则是\d{3}\-\d{3,8}

2-4、[]做更精确的匹配

[]匹配方括号中列出的任何单个字符。字符集允许你指定一组字符中的任意一个字符都应该匹配。

示例:

  • [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;

  • [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100''0_Z''js2015'等等;

  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]*可以匹配由字母或下划线、开头,后接任意个由一个数字、字母或者下划线、组成的字符串,也就是JavaScript允许的变量名;

  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)

三、JavaScript中正则表达式的使用

JavaScript有两种方式创建一个正则表达式:

1、直接通过/正则表达式/写出来

2、通过new RegExp('正则表达式')创建一个RegExp对象。

两种写法是一样的。

javascript 复制代码
var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');

re1; // /ABC\-001/
re2; // /ABC\-001/

注意,如果使用第二种写法,因为字符串的转义问题,字符串的两个\\实际上是一个`。`

判断正则表达式是否匹配:

RegExp对象的test()方法用于测试给定的字符串是否符合条件

javascript 复制代码
        var res = new RegExp('ABC\\-001');
        console.log(res.test('ABC-001'));// true
        console.log(res.test('ABC-002'));// false

3-1、切分字符串

用正则表达式切分字符串比用固定的字符更灵活。

示例:

javascript 复制代码
'a b   c'.split(' '); // ['a', 'b', '', '', 'c']

无法识别连续的空格。

使用正则表达式:

javascript 复制代码
'a b   c'.split(/\s+/); // ['a', 'b', 'c']

加入,试试:

javascript 复制代码
'a,b, c  d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd']

再加入;试试:

javascript 复制代码
'a,b;; c  d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']

如果用户输入了一组标签,下次记得用正则表达式来把不规范的输入转化成正确的数组。

3-2、分组

除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。

()表示的就是要提取的分组(Group)。

1、RegExp.exec()方法

2、字符串的 match() 方法

示例:

javascript 复制代码
        var re = /^(\d{3})-(\d{3,8})$/;
        var match = re.exec('123-11111');
        console.log(match);// ['123-11111', '123', '111111']
        console.log(match[1]);//123
        console.log(match[2]);//11111
        console.log(re.exec('12-1111'));// null

        const regex = /(\d{4})-(\d{2})-(\d{2})/;
        const str = "2023-09-13";
        const matches = str.match(regex);
        console.log(matches);// ['2023-09-13', '2023', '09', '13']
        console.log(matches[1]);//2023

exec()方法和str.match()方法,在匹配成功后,会返回一个Array,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。

exec()方法和str.match()方法,在匹配失败时返回null

3-3、贪婪匹配

贪婪匹配是正则表达式中的一种匹配行为方式,它指的是匹配尽可能多的字符以满足整个正则表达式的匹配条件。在贪婪模式下,正则表达式引擎会尽可能多地匹配字符,直到无法继续匹配为止。如果有多个匹配可能,贪婪匹配会选择最长的匹配。

正则匹配默认是贪婪匹配。

示例:匹配出数字后面的0

javascript 复制代码
var re = /^(\d+)(0*)$/;
re.exec('102300'); // ['102300', '102300', '']

由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。

必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

javascript 复制代码
var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']

?紧跟在量词(如*+?{n,})后面时,它将该量词转变为非贪婪模式(也称作最小匹配或懒惰模式)。非贪婪量词会尽可能少地匹配字符。

javascript 复制代码
const greedyRegex = /<.*>/; // 贪婪匹配,会匹配到最后一个">"  
const lazyRegex = /<.*?>/;  // 非贪婪匹配,只匹配到第一个">"  
const str = "<tag1><tag2></tag2></tag1>";  
console.log(str.match(greedyRegex)); // 输出 ["<tag1><tag2></tag2></tag1>"]  
console.log(str.match(lazyRegex));   // 输出 ["<tag1>", "<tag2>", "</tag2>", "</tag1>"]

3-4、全局匹配

正则表达式的g标志用于表示全局搜索。当使用这个标志时,正则表达式会尝试匹配输入字符串中所有可能的子串,而不仅仅是第一个匹配项。

如果不使用g标志,正则表达式的exec()方法或字符串的match()方法只会返回第一个匹配项。而使用g标志后,这些方法会返回所有匹配项。

javascript 复制代码
var r1 = /test/g;
// 等价于:
var r2 = new RegExp('test', 'g');

全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引:

javascript 复制代码
var s = 'JavaScript, VBScript, JScript and ECMAScript';
var re=/[a-zA-Z]+Script/g;

// 使用全局匹配:
re.exec(s); // ['JavaScript']
re.lastIndex; // 10

re.exec(s); // ['VBScript']
re.lastIndex; // 20

re.exec(s); // ['JScript']
re.lastIndex; // 29

re.exec(s); // ['ECMAScript']
re.lastIndex; // 44

re.exec(s); // null,直到结束仍没有匹配到

正则表达式还可以指定i标志,表示忽略大小写,m标志,表示执行多行匹配。

3-5、小结

正则表达式,很强大,内容也很多,如果你经常遇到正则表达式的问题,你可能需要一本正则表达式的参考书。

相关推荐
m0_74825614几秒前
前端 MYTED单篇TED词汇学习功能优化
前端·学习
IT古董19 分钟前
【机器学习】机器学习的基本分类-半监督学习(Semi-supervised Learning)
学习·机器学习·分类·半监督学习
jbjhzstsl38 分钟前
lv_ffmpeg学习及播放rtsp
学习·ffmpeg
青い月の魔女1 小时前
数据结构初阶---二叉树
c语言·数据结构·笔记·学习·算法
网络安全(king)1 小时前
网络安全攻防学习平台 - 基础关
网络·学习·web安全
qq_589568101 小时前
node.js web框架koa的使用
笔记·信息可视化·echarts
小马哥编程1 小时前
Function.prototype和Object.prototype 的区别
javascript
王小王和他的小伙伴1 小时前
解决 vue3 中 echarts图表在el-dialog中显示问题
javascript·vue.js·echarts
虾球xz2 小时前
游戏引擎学习第59天
学习·游戏引擎
学前端的小朱2 小时前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具