JS正则基础知识

1 正则相关属性和方法

1.1 lastIndex属性

当作为正则表达式对象的方法使用时,要特别注意它的lastIndex属性。

lastIndex从字面上来讲就是最后一个索引,实际上它的意思是正则表达式开始下一次查找的索引位置,第一次的时候总是为0的。

非全局模式lastIndex属性 不生效

1.2 匹配方法test()

Regex.test(str);

当正则在全局模式下使用test方法时需要注意一个问题 例子如下:

var re=/[a-z]\d/g;
console.log(re.lastIndex)//0
console.log(re.test('a1b2c3'))//true
console.log(re.lastIndex)//2
console.log(re.test('a1b2c3'))//true
console.log(re.lastIndex)//4
console.log(re.test('a1b2c3'))//true
console.log(re.lastIndex)//6
console.log(re.test('a1b2c3'))//false
console.log(re.lastIndex)//0
console.log(re.test('a1b2c3'))//true

由于lastIndex总是指向下一次查找开始的地方,在第三次判断的时候lastIndex已经为6了,所以为false;

1.3 提取匹配项 match()

let ourStr = "Regular expressions";
let ourRegex = /expressions/;
ourStr.match(ourRegex); //["expressions"]

.match语法是目前为止一直使用的 .test方法中的“反向”:

'string'.match(/regex/);
/regex/.test('string');

2 重点标识

2.1 修饰符

i ———— 忽略大小写的标志 例:/ignorecase/i

g ———— 全局匹配 例:/ignorecase/g

m ———— 多行匹配 例:

let str = "@123
@456
@789
"
str.replace(/@\d/g,'x') 
/*"x23
@456
@789
"*/
//因为有换行符的存在所以下面@不能算作字符串的开头
str.replace(/@\d/gm,'x') 
/*"x23
x456
x789
"*/
//这时候m就派上用处了

2.2 范围类

[]———— 字符集 例:/b[aiu]g/ 只能匹配bag big bug

  • ———— 连字符 例:/[a-e]at/ 要匹配小写字母 ae,可以使用 [a-e] ,数字同理 两者还能同时使用 例:/[a-z0-9]/ig

2.3 预定义类

. ———— 通配符 例:/.un/ 可以匹配run gun等;等价类为[^\r\n],除了回车符和换行符之外的所有字符。

\w ———— 等同于[A-Za-z0-9_] 单词字符(字母、数字下划线)

\W ———— 等同于[^A-Za-z0-9_] 非单词字符

\d ———— 等同于[0-9] 数字字符

\D ———— 等同于[^0-9] 非数字字符

\s ———— 空白符。此匹配模式将匹配空格、回车符、制表符、换页符和换行符;似于元字符 [ \r\t\f\n\v]

\S ———— 非空白符。此匹配模式将匹配空格、回车符、制表符、换页符和换行符;似于元字符 [ \r\t\f\n\v]

2.4 边界字符

^ ———— 以xxx开始 例:/[^aeiou]/gi/ 这是一个不想匹配的字符集合 ,这里只不匹配元音字符,字符 .![@/和空白字符等也会被匹配

字符^的另外一个作用是匹配字符串的开头 如:

let firstString = "Ricky is first and can be found.";
let firstRegex = /^Ricky/;
let secondString = "icky is first and can be found.";
console.log(firstRegex.test(firstString))//true
console.log(firstRegex.test(secondString)) //false

$ ———— 以xxx结束。 例:

let theEnding = "This is a never ending story";
let storyRegex = /story$/;
storyRegex.test(theEnding);//true
let noEnding = "Sometimes a story will have to end";
storyRegex.test(noEnding);//false

\b ———— 单词边界

\B ———— 非单词边界

2.5 量词

?———— 出现一次或零次。 可以将此符号视为前面的元素是可选的。例:

let american = "color";
let british = "colour";
let rainbowRegex= /colou?r/;
rainbowRegex.test(american);//true
rainbowRegex.test(british);//true
  • ———— 匹配一次或者连续多次的的字符(至少出现一次) 例:/a+/g 会在 abc中匹配到一个匹配项,并且返回 ["a"]。 因为 +的存在,它也会在 aabc 中匹配到一个匹配项,然后返回 ["aa"]
  • ———— 出现零次或多次(任意次) 例:/go*/ 可以匹配出现零次或多次的字符 具体示例如下:
let soccerWord = "gooooooooal!";
let gPhrase = "gut feeling";
soccerWord.match(goRegex); //["goooooooo"]
gPhrase.match(goRegex); //["g"]

{n} ———— 出现n次。例,要匹配出现 3次字母 a的在字符串 ah,正则表达式应为/a{3}h/

{n,m} ———— 出现n到m次 例:

let A4 = "aaaah";
let A2 = "aah";
let multipleA = /a{3,5}h/;
multipleA.test(A4);//true
multipleA.test(A2);//false

{n,} ———— 至少出现n次。例:匹配至少出现 3次字母 a的字符串 hah,正则表达式应该是 /ha{3,}h/

{,m} ———— 最多出现m次。

2.6 非贪婪模式

正则默认是贪婪模式

?———— 懒惰匹配(非贪婪模式) 例:/t[a-z]*i/ 应用于字符串 "titanic"。 这个正则表达式是一个以 t开始,以 i结束,并且中间有一些字母的匹配模式。正则表达式默认是贪婪匹配,因此匹配返回为 ["titani"]。 它会匹配到适合该匹配模式的最大子字符串。以使用 ?字符来将其变成懒惰匹配。 调整后的正则表达式 /t[a-z]*?i/ 匹配字符串 "titanic"返回 ["ti"]

2.7 分组

分组需要使用()

具体例子如何

//分组前
'a1b2c3d4'.replace(/[a-z]\d{3}/g,'x');//a1b2c3d4
//分组后
'a1b2c3d4'.replace(/([a-z]\d){3}/g,'x');//xd4

2.8 或

使用 | 可以达到或的效果

'DeanWinnie'.replace(/Dean|Winnie/g,'x')//xx
'DeanDenise'.replace(/De(an|nise)/g,'x')//xx

2.9 反向引用

用$加数字来代表各个分组 需要配合分组使用 不然是无效的具体例子如下

"2022-02-22".replace(/(\d{4})-(\d{2})-(\d{2})/,'$2/$3/$1')//02/22/2022

2.10 忽略分组

不希望捕获的分组,只需要在分组内加上?:就可以了 例如

'deanwinnie'.replace(/(?:dean)(winnie)/,'$1$2')//winnie$2  这时候只存在分组1,且分组1为winnie

2.11 前瞻

前瞻就是在正则表达式匹配到规则的时候,向前检查是否复核断言,

(?=…) ———— 正向前瞻即正向先行断言,正向先行断言会查看并确保搜索匹配模式中的元素存在,但实际上并不匹配。例:

let quit = "qu";
let qua = 'qa'
let quRegex= /q(?=u)/;
quit.match(quRegex);//true
qua.match(quRegex);//false

(?!..)————负向前瞻即负向先行断言**。**希望不存在的匹配模式。 如果负向先行断言部分不存在,将返回匹配模式的其余部分。例:

let quit = "qu";
let noquit = "qt";
let qRegex = /q(?!u)/;
quit.match(qRegex);//false
noquit.match(qRegex);//true

3 练习题

3.1 限制可能的用户名

  1. 用户名只能是数字字母字符。
  2. 用户名中的数字必须在最后。 数字可以有零个或多个。 用户名不能以数字开头。
  3. 用户名字母可以是小写字母和大写字母。
  4. 用户名长度必须至少为两个字符。 两位用户名只能使用字母。
//方案一
let userCheck = /^[a-z][a-z]+\d*$|^[a-z]\d\d+$/i;

代码解读

  1. ^ 输入开始
  2. [a-z]第一个字符是一个字母
  3. [a-z]+后面的字符是字母
  4. \d*$输入以 0 位或更多位数字结尾
  5. |或者
  6. ^[a-z]第一个字符是一个字母
  7. \d\d+以下字符为 2 位或更多位
  8. $输入结束
//方案二
let userCheck = /^[a-z]([0-9]{2,}|[a-z]+\d*)$/i;
  1. ^输入开始
  2. [a-z]第一个字符是一个字母
  3. [0-9]{2,0}以两个或多个数字结尾
  4. |或者
  5. [a-z]+接下来有一个或多个字母
  6. \d*并以零个或多个数字结尾
  7. $输入结束
  8. i忽略输入的大小写
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值