浅谈js正则表达式

556 阅读4分钟

正则表达式是什么?

正则表达式是一种字符串的匹配方法,由普通字符与元字符构成。其实就是作为某种字符串模板,与某一个字符串进行匹配。

主要语法

正则表达式写在 // 中,在 // 中间写正则表达式的语法,^符号表示以后面的字符开头,$表示以前面的字符结尾。

/^[0-9]+$/gi

字符规则

普通字符:

普通字符就是在键盘中可以敲出的任意字符,都可以写在正则表达式中进行匹配:

/abcdefg123,.;/

元字符:

元字符比较复杂,有普通元字符,特殊元字符,限定符,修饰符等

  • 普通元字符

字符描述
\f匹配一个换页符。等价于 \x0c\cL
\n匹配一个换行符。等价于 \x0a\cJ
\r匹配一个回车符。等价于 \x0d\cM
\t匹配一个制表符。等价于 \x09\cI
\v匹配一个垂直制表符。等价于 \x0b\cK
\b匹配一个单词边界。单词和空格间的位置,例如,er\b可以匹配over中的er,而不可以匹配serve中的er
\B匹配一个非单词边界
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
\d匹配数字字符。等价于 [0-9]
\D匹配非数字字符。等价于 [^0-9]
\w匹配字母、数字、下划线。等价于[A-Za-z0-9_]
\W匹配非字母、数字、下划线。等价于[^A-Za-z0-9_]
  • 特殊元字符

字符描述
^匹配输入字符串的开始位置,当出现在[]中时表示不匹配中括号中的规则。
$匹配输入字符串的结束位置。
( )子表达式开始和结束的位置。子表达式可以获取供后使用(通过【$n】使用)。
[ ]中括号表达式,表示匹配中括号中的任意字符。
.表示匹配任意非换行的字符。
\将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。
|表示一个选择字符,例:/(a|b)/,匹配a或者b
  • 限定符

字符描述
*匹配前面的子表达式零次或多次。
+匹配前面的子表达式一次或多次。
匹配前面的子表达式零次或一次。
{n}n 是一个非负整数。匹配确定的 n 次。
{n,}n 是一个非负整数,至少匹配 n 次。
{m,n}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。
  • 修饰符

字符描述
g全局匹配。
i不区分字母大小写。
m多行匹配。
s特殊元字符 “ . ” 中包含换行符。
y粘性匹配,会在lastIndex的位置开始进行匹配。

匹配api

正则表达式api

  • exec:reg.exec(str)
    • 匹配成功返回:一个数组,[0]项为匹配的全部字符串,[0],...[n]为小括号中的分别捕获,还有额外属性index为匹配到的原始字符串的基于0的索引值,input为原始字符串;
    • 匹配失败返回:null;
let reg = /quick\s(brown).+?(jumps)/ig;
let result = reg.exec('The Quick Brown Fox Jumps Over The Lazy Dog');
//   [0: "Quick Brown Fox Jumps",
//    1: "Brown",
//    2: "Jumps",
//    groups: undefined,
//    index: 4,
//    input: "The Quick Brown Fox Jumps Over The Lazy Dog",
//    length:3]
let reject = reg.exec('aaaaaaa');
//   null
  • test:reg.test(str)
    • 匹配成功返回:true;
    • 匹配失败返回:false;
let reg = /^\/[a-zA-Z0-9]+$/;
let result = reg.test('/abc0');  // true
let reject = reg.test('//--a8');  //false

字符串api

  • search:str.search(reg)
    • 匹配成功返回:首次匹配项的索引下标;
    • 匹配失败返回:-1;
let str = "hello world!";
let reg = /[^\w]/g;
let result = str.search(reg); // 5
  • match:str.match(reg)
    • 匹配成功返回:如果是全局匹配则返回匹配结果的数组;如果没有全局匹配则返回一个带有特殊属性的数组,第[0]项为匹配结果,groups属性为捕获数组名活undefined,index属性为匹配到结果的开始下标位置,input属性为原始字符串;
    • 匹配失败返回: null; 如果正则表达式不包含 g 标志,str.match() 将返回与 RegExp.exec()相同的结果。
let regG = /[A-Z]/g;
let reg = /[A-Z]/;
let str = "Hello World!";
str.match(regG); //["H","W"]
str.match(reg); 
/*[
    0:"H",
    groups: undefined,
    index: 0,
    input: "Hello World!"
  ]
*/
  • replace:str.replace(reg, '替换字符串')
//例:将手机号码中间四位换成"****"
let reg = /^1(\d{2})\d{4}(\d{4})$/g;
let tell = "15807928848";
let result = tell.replace(reg, "1$1****$2"); //158****8848
//其中$1表示reg中子表达式(\d{2})的匹配结果,$2表示reg中子表达式(\d{4})的匹配结果

$1--$9 是RegExp 自带的,只要发生了匹配就会有。代表的是 分组,即小括号里面的小正则 捕获到的内容。/^(\d{4})[/-](\d{1,2})[/-](\d{1,2})$/比如这个 简单的匹配 年月日的正则,我们就可以通过 $1,$2,$3 获取到并进行处理。

  • split:str.split(reg)

高级

声明词量

  • 正向声明(?= 匹配条件):指定匹配模式后面的字符必须被匹配,但又不返回这些字符(就是说匹配模式后面紧跟着的字符必须满足匹配条件才能匹配成功)
`匹配模式`(?= `匹配条件`)
let reg = /(\d)+(?=d)/g;
let str = 'd123abc456def';
reg.exec(str);// ['456','6',index: 7, input: 'd123abc456def', groups: undefined]
  • 反向声明(?! 匹配条件):与正向声明匹配相反,指定接下来的字符都不必被匹配(就是说匹配模式后面紧跟着的字符必须不能满足匹配条件才能匹配成功)
`匹配模式`(?! `匹配条件`)
let reg = /(\d){3}(?!d)/g;
let str = 'd123abc456def';
reg.exec(str);// ['123','3',index: 1, input: 'd123abc456def', groups: undefined]

引用

  • 反向引用:\数字序号(特殊的转义) 数字指定了子表达式在匹配模式中的顺序。如“\1”引用的是第 1 个子表达式,“\2”引用的是第 2 个子表达式。
let str = "a3 3 a 3a";
let reg = /(\w)(\d)(\s)\2\3\1\3\2\1/;
reg.test(str); // true
  • 禁止引用: ?: 在较长的正则表达式中,反向引用会降低匹配速度,如果分组仅仅是为了方便操作,可以禁止反向引用。
let str = "Harry Trump ;Fred Barney; Hello ";
let reg = /\s*(?:;|$)\s*/;
str.split(reg); // ["Harry Trump", "Fred Barney", ""]