博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js 正则表达式
阅读量:7010 次
发布时间:2019-06-28

本文共 5556 字,大约阅读时间需要 18 分钟。

参考资料:

创建正则表达式对象

有两种创建正则表达式的方式

  1. 字面量

    • 在脚本加载后编译
    • 正则表达式是静态的时候性能会比较高
  2. 构造函数

    • 正则表达式运行时编译
    • 适合需要动态更改规则的情况
let reg1 = /ab+c/;                  // 字面量let reg2 = new RegExp('ab+c');      // 构造函数let reg3 = new RegExp('/ab+c/');let reg4 = new RegExp(/ab+c/, i);   // 同等 /ab+c/i

使用构造函数创建正则时,第二个参数只能传 "g""i""m",否则会出异常。

简单的使用

先看一个匹配qq号的例子,然后再根据这个例子往下看,这样学起来会相对轻松。

qq号的规则:

  1. 全是数字
  2. 不能以0开头 -> ^[1-9]{1} 简化-> ^[1-9]
  3. 最低5位,最高10位 -> [0-9]{4,9}$ 简化-> \d{4,9}$
let reg = /^[1-9]{1}\d{4,9}$/;reg.test('1234567890');    // truereg.test('12345678901');    // falsereg.test('0234567890');    // false

修饰符( i g m )

名称 描述 例子
i 对大小写不敏感 /abc/i
g 全局匹配(不会在第一次匹配成功后停止) /abc/g
m 多行匹配 /abc/m

正则表达式默认匹配成功后就不会继续匹配。如果想匹配字符串中所有符合的子串,就要加g

字符范围( [] )

使用[]表示定义匹配字符的范围。

let reg = /[a-zA-z0-9]/;    //匹配小写和大写的a-z还有0-9console.log(reg.test('A'));  // trueconsole.log(reg.test('@'));  // false

reg.test()方法是RegExp对象方法,匹配成功返回true,否则返回false

量词

量词 描述 例子
n{x} 匹配包含 X 个 n 的序列的字符串。 /[0-9]{4}/
n{x,y} 匹配包含 X 至 Y 个 n 的序列的字符串。 /[0-9]{4,6}/
n{x,} 匹配包含至少 X 个 n 的序列的字符串。 /[0-9]{4,}/
n* 匹配任何包含零个或多个 n 的字符串。 /n*/
n+ 匹配任何包含至少一个 n 的字符串。 /n+/
n? 匹配任何包含零个或一个 n 的字符串。 /n?/
n$ 匹配任何结尾为 n 的字符串。 /n$/
^n 匹配任何开头为 n 的字符串。 /^n/
?=n 匹配任何其后紧接指定字符串 n 的字符串。 /lo(?= java)/
?!n 匹配任何其后没有紧接指定字符串 n 的字符串。 /lo(?! java)/

{x} {x,y} {x,}

reg.test()方法,匹配字符串,匹配成功返回true,否则返回false

  • n{x} 匹配包含 X 个 n 的序列的字符串。
let reg = /[0-9]{4}/; // 匹配4位连续的子串,范围是0-9的数值reg.test('1234');   // truereg.test('123');    // falsereg.test('12a45');  // false
  • {x,y}:匹配包含 X 至 Y 个 n 的序列的字符串。
let reg = /[0-9]{4,6}/; // 匹配4~6位连续的子串,范围是0-9的数值reg.test('12345');   // truereg.test('123');    // falsereg.test('123a56');  // false
  • {x,}:匹配包含至少 X 个 n 的序列的字符串。
let reg = /[0-9]{4,}/; // 匹配最少4位连续的子串,范围是0-9的数值reg.test('12345');   // truereg.test('123');    // falsereg.test('123a567');  // false

* + ?

reg.exec(),这个方法和test()差不多,区别在于返回值。匹配成功会返回一个数组,匹配失败会返回null

返回值的数组中还有一个index的参数,这个参数是匹配到的子串所在字符串的起始索引。

*+?这仨解释起来有点绕,直接看代码会秒懂。

  • *:匹配任何包含零个多个 n 的字符串。
let reg = /n*/;reg.exec('n');      // ['n']reg.exec('nnn');    // ['nnn']reg.exec('aaa');    // [''],字符串中没有n,但是*可以匹配没有n的情况(零个)
  • +:匹配任何包含至少一个 n 的字符串。
let reg = /n+/;reg.exec('n');      // ['n']reg.exec('nnn');    // ['nnn']reg.exec('aaa');    // null
  • ?:匹配任何包含零个一个 n 的字符串。
let reg = /n?/;reg.exec('n');      // ['n']reg.exec('nnn');    // ['n'],无论有多少个连续的n,都只会匹配到一个。reg.exec('aaa');    // ['']

^和$(开头和结尾)

  • ^:匹配任何开头为 n 的字符串。
let reg = /^n/;reg.test('nbcd');   // truereg.test('efghn');  // fasle
  • $:匹配任何结尾为 n 的字符串。
let reg = /n$/;reg.test('nbcd');   // faslereg.test('efghn');  // true

?= 和 ?!

  • ?=n:匹配任何其后紧接指定字符串 n 的字符串。
// 匹配 lo,但是这个lo要在' java'之前let reg = /lo(?= java)/;    // 注意空格reg.exec('hello javascript');   // ['lo'], index: 3
  • ?!n:匹配任何其后没有紧接指定字符串 n 的字符串。
// 匹配 lo,但是这个lo不能在' java'之前let reg = /lo(?! java)/;    // 注意空格reg.exec('hello javascript lo');   // ['lo'], index: 17

提取匹配字符串( () )

使用()提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串。

可以通过$x的方式提取出来。(x表示一个数字)

let reg = /([\w]+?)bc([\d])/;let str = 'abc123';reg.exec(str);  // ['abc1', 'a', '1'],第二个元素是$1,第三个元素是$2str.replace(reg, '$1$2');   //a123, reg匹配到的是'abc1',匹配到的字符串用$1和$2替换掉,所以结果是 a123

元字符

元字符 描述 例子
. 查找单个字符,除了换行和行结束符。 /h.t/ -> 'hxt'
\w 查找单词字符。 /\w/
\W 查找非单词字符。 /\W/
\d 查找数字。 /\d/
\D 查找非数字字符。 /\D/
\s 查找空白字符。 /\s/
\S 查找非空白字符。 /\S/
\b 匹配单词边界。 /\b/
\B 匹配非单词边界。 /\B/
\0 查找 NUL 字符。 /\0/
\n 查找换行符。 /\n/
\f 查找换页符。 /\f/
\r 查找回车符。 /\r/
\t 查找制表符。 /\t/
\v 查找垂直制表符。 /\v/
\xxx 查找以八进制数 xxx 规定的字符。 /\127/ ->匹配'W'字符
\xdd 查找以十六进制数 dd 规定的字符。 /\x57/ -> 匹配'W'字符
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。 /\u0057/ -> 匹配'W'字符

RegExp对象属性

属性 描述
global RegExp对象是否具有标志 g
ignoreCase RegExp对象是否具有标志 i
lastIndex 一个整数,标识开始下一次匹配的字符位置
multiline RegExp对象是否具有标志 m
source 正则表达式的源文本

RegExp对象方法

test()

检索字符串中指定的值,返回true或者false。这个方法比较常用。

let reg = /hello \w{3,12}/; // 匹配'hello '(注意空格)后面的 3到12个字符alert(reg.test('hello js'));    // falsealert(reg.test('hello javascript')) // true

exec()

检索字符串中指定的子串,匹配成功返回一个数组,匹配失败返回null

let reg = /hello/;console.log(reg.exec('hellojs'));   // ['hello']console.log(reg.exec('javascript'));    // null
  • index: 子串起始位置
  • input: 被检索的字符串

compoile()

改变RegExp,可以改变检索模式,也可以添加或删除第二个参数

let reg = /hello/;console.log(reg.exec('hellojs'));   // ['hello']reg.compile('Hello');   // 改变为 /Hello/console.log(reg.exec('hellojs'));   // nullreg.compile('Hello', 'i');  // 改变为 /Hello/iconsole.log(reg.exec('hello')); // ['hello']

String对象的正则方法

除了RegExp对象提供方法之外,String对象也提供了四个方法来使用正则表达式。

match()

匹配指定的值,匹配成功返回结果数组,否则返回null。

如果没有设置全局匹配g,则会匹配一次成功立刻返回。

console.log('js js js js'.match( /js/i ));      //['js']console.log('js js js js'.match( /js/gi ));     //['js', 'js', 'js', 'js']

search()

匹配指定的值,匹配成功返回第一个匹配成功的子串索引,否则返回-1

console.log( 'hello,hello'.search( /lo/i ) );   // 3

replace()

替换匹配成功的子串,并返回替换后的字符串。

不设置全局匹配g的时候只会替换第一个匹配成功的子串

console.log('hello js, hello html'.replace( /hello/i, 'hi' ) ); // hi js, hello htmlconsole.log('hello js, hello html'.replace( /hello/ig, 'hi' ) ); // hi js, hi html

split()

把字符串分割成数组

console.log( 'one1-two2-tree3-four'.split( /[1-3]-/ ) );    // ["one", "two", "tree", "four"]

匹配国内电话号码

电话号码的规则:

一般都是 区号 + 电话号码

0555-6581752、020-86128488

  1. 区号以0开头。 ^0
  2. 区号3位或者4位(算上开头的0)。 \d{2}
  3. 区号的电话号码之间有-符号。 -
  4. 电话号码不能以0开头。 [1-9]
  5. 3位的区号对应8位的电话号码,4位的区号对应7位的电话号码。\d{7}$
// let reg1 = /^0\d{2}-[1-9]\d{7}$/;   // 匹配3位区号的电话号码// let reg2 = /^0\d{3}-[1-9]\d{6}$/;   // 匹配4位区号的电话号码// 合在一起let numReg = /(^0\d{2}-[1-9]\d{7}$)|(^0\d{3}-[1-9]\d{6}$)/;numReg.test('0555-6581752');    // truenumReg.test('020-86128488');    // true

匹配邮箱

登录名@主机名.域名

邮箱规则:

  1. 登录名允许 数字、英文和下划线,长度不确定。[\w\d_]{1,}
  2. 有一个@符号。 @
  3. 主机名允许 数字和英文,长度不确定。 [\w\d]{1,}
  4. 有一个.符号。\.
  5. 域名只允许英文。 \w{1,}$
let reg = /^[\w\d_]{1,}@[\w\d]{1,}\.\w{1,}$/;reg.test('example@163.com');

转载地址:http://fcntl.baihongyu.com/

你可能感兴趣的文章