JavaScript 正则表达式的元字符详解

🌙
手机阅读
本文目录结构

元字符

  • 单个字符数字
    • . 匹配除换行符以外的任意字符
    • [a-zA-Z0-p] 与 [^a-zA-Z0-p] 匹配方括号中的任意字符,前面代 ^ 是匹配不在方括号中的任意字符;
    • \d 与 \D 匹配数字和匹配非数字;
    • \w 与 \W 匹配字符和匹配非字母
  • 空白字符
    • \O 匹配 null 字符
    • \b 匹配空格字符
    • \f 匹配换页符
    • \n 匹配换行符
    • \r 匹配回车符
    • \s 和 \S 匹配空白字符,空格、制表符或换行符。大写的 S 是匹配非空字符
    • \t 匹配制表符
  • 定位符
    • ^ 行首匹配
    • $ 行尾匹配
    • \A 只匹配字符串的开始处
    • \b \B 匹配单词便捷,词在 [] 内无效,匹配非单词边界
    • G 匹配当前搜索的开始位置
    • \Z \z 匹配字符串结束处或行尾,只匹配字符串结束处
  • 限定符
    • x? 匹配 0 个或一个 x
    • x* 匹配 0 个或者任意多个 x
    • x+ 匹配一个或者多个
    • x{m,n} 匹配 m-n 个 x;
  • 分组
    • (?:x) 匹配 x 但不记录匹配结果(匹配不捕获)
    • x(?=y) 当 x 后面接 y 时匹配 x
    • x(?!y) 当 x 后不是 y 时匹配 x
  • 引用
    • \1…\9 $1…$9 返回就割在模式匹配期间找到的,最近保存的部分
  • 或模式
    • x|y|z 匹配 x 或者 y 或者 z

正则的组成

var reg = /\d/;//->包含一个 0-9 之间的数字
console.log(reg.test("zhu"));//->false
console.log(reg.test("zhu1"));//->true

var reg2 = /^\d$/;//->只能是一个 0-9 之间的数字
console.log(reg2.test("9"));//->true
console.log(reg2.test("012"));//->false

正则是由元字符组成的:

每一个正则表达式都是由元字符和修饰符组成的

什么是【元字符】:在 // 之间具有意义的一些字符

  • 1、具有特殊意义的元字符

    • : 转义字符,转译后面字符所代表的含义

    • ^: 以某一个元字符开始

    • $: 以某一个元字符结尾

    • \n: 匹配一个换行符

    • .: 除了、n 以外的任意字符

        var reg = /^0.2$/;//->以 0 开头,以 2 结尾,中间可以是除了、n 的任意字符
        console.log(reg.test("0.2"));//->true
        console.log(reg.test("0 和 2"));//->true
        console.log(reg.test("0-2"));//->true
        console.log(reg.test("0sdhfohsdf-2"));//->false
      
        reg = /^0\.2$/;//->以 0 开头,以 2 结尾,中间是。的字符串;
        console.log(reg.test("0.2"));//->true
        console.log(reg.test("0-2"));//->false
      
    • (): 功能一:分组 ->把一个大正则本身划分成几个小的正则

        var reg1 = /^\d+zhu\d+$/;
        var reg2 = /^(\d+)zhu(\d+)$/;
      
        // 匹配
        console.log(reg1.test("2zhu3"));//true
        console.log(reg2.test("2zhu4"));//true
        // 捕获
        console.log(reg1.exec("2zhu3"));//["2zhu3", index: 0, input: "2zhu3"]
        console.log(reg2.exec("2zhu4"));//["2zhu4", "2", "4", index: 0, input: "2zhu4"]
      
      • 功能二:改变|的优先级;功能:替换,“或"操作字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food”。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。
    • x|y:x 或者 y 中的一个

    • ^x|yz$:x 开头、yz 结尾、x 开头并且 yz 结尾、三种都可以

    • [xyz]:x 或者 y 或者 z 中的一个

    • [a-z]:a-z 之间的任何一个字符

    • \d: 一个 0-9 之间的数字 \D: 除了 0-9 之间的数字以外的任何字符

    • \b: 匹配一个边界符

    • \w: 数字、字母、下划线中的任意一个字符 [0-9a-zA-Z_]

    • \s: 匹配一个空白字符 空格、一个制表符、换页符。..

  • 2、代表出现次数的量词元字符

    • *: 出现零到多次

    • +: 出现一到多次

    • ?: 出现零次或者一次

    • {n}: 出现 n 次

    • {n,}: 出现 n 到多次

    • {n,m}: 出现 n 到 m 次

        var reg = /^\d+$/;
        console.log(reg.test("2015"));//->true
      

一个简单的验证手机号的正则:11 位数字,第一位是 1

var reg = /^1[3|4|5|7|8]\d{9}$/;// 第一位以 1 开始,第二位可以是 34578 中的任意一位,后面再加 9 个数字;
console.log(reg.test("12345678901"));//false
console.log(reg.test("13856487589"));//true
console.log(reg.test("12114567895"));//false

[] 整括号的注意

  • 1、在整括号中出现的所有的字符都是代表本身意思的字符(没有特殊的含义,\d 这种特殊)

      var reg = /^[.]\d+$/;
      console.log(reg.test("46545"));//->false
      console.log(reg.test(".89"));//->true
    
      var reg1 = /^[.]\d+[+]$/;
      console.log(reg1.test("46545"));//->false
      console.log(reg1.test(".89+"));//->true
    
      var reg2 = /^[.]\d+0[\d+]$/;
      console.log(reg2.test("46545"));//->false
      console.log(reg2.test(".465045"));//->true 如果是 465045 就是 false
      console.log(reg2.test(".890+"));//->true
    
  • 2、整括号中不识别两位数,整括号内是多个取一个

      var reg1 = /^[12]$/;//->1 或者 2 中的一个
      console.log(reg1.test("12"));//false
      console.log(reg1.test("1"));//true
      console.log(reg1.test("2"));//true
    
      var reg2 = /^[12-48]$/;//->1、2-6 中的一个、8 三个中的一个
      console.log(reg2.test("128"));//false
      console.log(reg2.test("138"));//false
      console.log(reg2.test("158"));//false
      console.log(reg2.test("1"));//true
      console.log(reg2.test("3"));//true
      console.log(reg2.test("5"));//true
      console.log(reg2.test("8"));//true
      console.log(reg2.test("13"));//false
    
      var reg = /^[\w-]$/;//->数字、字母、下划线、- 中的一个
      console.log(reg.test("-"));//true
      console.log(reg.test("89"));//false
      console.log(reg.test("_"));//true
    

() 整括号的另外作用:改变 x|y 的默认的优先级;

|的优先级很高;

功能:替换,“或"操作字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food”。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。

	var reg1 = /^18|19$/;
	// 错误分析:想匹配 119 和 189,1 开始,9 结尾,中间是 8 或者 1 的任意一个;
	// 实际可以这些数字都是可以匹配成功的:18、19、181、189、119、819、1819...
	console.log(reg1.test("19"));//true
	console.log(reg1.test("18"));//true
	console.log(reg1.test("119"));//true
	console.log(reg1.test("189"));//true
	console.log("test 189999999999",reg1.test("189999999999"));//true
	console.log("test 819",reg1.test("819"));//true
	console.log("test 1819",reg1.test("1819"));//true
	console.log("test 1889899819",reg1.test("1889899819 "));//true

	// 正确分析:18|19 可以匹配 18 开头或者 19 结尾的;(18 开头)、(19 结尾)、(18 开头和 19 几位的),都可以匹配成功;

	//|替换,"或"操作字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。

	var testReg1=/m|food/;
	// 匹配 (m 开头)、(food 结尾)、(m 开头或者 food 结尾);这三种都可以匹配
	console.log("test m",testReg1.test("m"));//true
	console.log("test m464545646565",testReg1.test("m464545646565"));//true
	console.log("test mood",testReg1.test("mood"));//true
	console.log("test food",testReg1.test("food"));//true
	var testReg2=/(m|f)ood/;
	// 匹配 mood/food
	console.log("test m",testReg2.test("m"));//false
	console.log("test m464545646565",testReg2.test("m464545646565"));//false
	console.log("test mood",testReg2.test("mood"));//true
	console.log("test food",testReg2.test("food"));//true

	var reg2 = /^(18|19)$/;
	//18、19
	console.log(reg2.test("19"));//true
	console.log(reg2.test("18"));//true
	console.log(reg2.test("119"));//false
	console.log(reg2.test("189"));//false

	var reg3 = /^1[8|1]9$/;
	//119、189
	console.log("test 19",reg3.test("19"));//false
	console.log(reg3.test("18"));//false
	console.log(reg3.test("119"));//true
	console.log(reg3.test("189"));//true

正则实践

  • 1、有效数字的正则(可以是 正数、负数、零、小数 )

    • 1)、".“可以出现也可以不出现,但是一旦出现,后面必须跟着一位或者多位数字

    • 2)、最开始可以有 +/- 也可以没有

    • 3)、整数部分,一位数可以是 0-9 之间的一个,多位数不能以 0 开头

        var reg = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/;//. 是一个元字符,所以需要转义;
        console.log("test +1",reg.test("+1"));//true
        console.log("test +-1",reg.test("+-1"));//false
        console.log("test -1.001",reg.test("-1.001"));//true
        console.log("test -1.001.002",reg.test("-1.001.002"));//false
        console.log("test 0",reg.test("0"));//true
      
  • 2、年龄介于 18~65 之间

    • 18~65 可以分为三份;18-19 20-59 60-65

    • 因为 1 开头的不能是 12,15,14 这些;

    • 6 开头的不能是 66,68 这些;

    • 2 和 5 开头,后面可以随便,0-9 都可以;

        var reg = /^(1[8-9]|[2-5]\d|6[0-5])$/;
        console.log("test 18",reg.test("18"));//true
        console.log("test 12",reg.test("12"));//false
        console.log("test 20",reg.test("20"));//true
        console.log("test 65",reg.test("65"));//true
        console.log("test 69",reg.test("69"));//false
      
  • 3、验证邮箱的正则(简版)

    • 左边:数字、字母、下环线、.、-

        var reg = /^[\w.-]+@[0-9a-zA-Z]+(\.[a-zA-Z]{2,4}){1,2}$/;
        /*
        * \w: 数字、字母、下划线中的任意一个字符  [0-9a-zA-Z_]
        * [\w.-]:[\w]、[.]、[-] 三者中的任意一个,出现一次或者多次;
        * [0-9a-zA-Z]: 大小写,或者数字;
        * (\.[a-zA-Z]{2,4})  . 后面加 2-4 位大小写的域名,比如。com .cn
        * {1,2} 出现一次或者两次。可能是顶级域名,也可能是二级域名;
        * */
        console.log(reg.test("weqwes@sina.com.cn"));//true
      
  • 4、汉字昵称 2-4 位汉字

      	var reg = /^[\u4e00-\u9fa5]{2,4}$/;
    
  • 5、身份证号码

      var reg1 = /^\d{17}(\d|X|x)$/;
    
      //342224199004281111X
      var reg2 = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X|x)$/;
    
      console.log("test 34222819000428111x",reg1.test("34222819000428111x"));//true
      console.log("test 34222819000428111X",reg1.test("34222819000428111X"));//true
      console.log("test 34222819000428111x",reg2.test("34222819000428111x"));//true
      console.log("test 34222819000428111X",reg2.exec("34222819000428111X"));//["34222819000428111X", "34", "2228", "1900", "04", "28", "11", "1", "X", index: 0, input: "34222819000428111X"]
    
    1. 匹配整数或者 0-8 位小数;

    const test0 = “01”;//true const test1 = “1.”;//true const test2 = “5”;//true const test3 = “999999999.34546782”;//true const test4 = “5.10”;//true

    const test5 = “123.45678.908”;//false const test6 = “1s34.5678”;//false const test7 = “1s34.3454678332”;//false const test8 = “123.45678.”;//false

代码如下

const reg=/^\d{1,}\.?\d{0,8}$/;

const test0 = "01";//true
const test1 = "1.";//true
const test2 = "5";//true
const test3 = "999999999.34546782";//true
const test4 = "5.10";//true

const test5 = "123.45678.908";//false
const test6 = "1s34.5678";//false
const test7 = "1s34.3454678332";//false
const test8 = "123.45678.";//false

console.log(reg.test(test0));
console.log(reg.test(test1));
console.log(reg.test(test2));
console.log(reg.test(test3));
console.log(reg.test(test4));
console.log("----");
console.log(reg.test(test5));
console.log(reg.test(test6));
console.log(reg.test(test7));
console.log(reg.test(test8));

正则表达式由三部分组成

  • 普通字符
    • 例如字符 a 到 z
  • 元字符
  • 修饰符

正则表达式是由普通字符,元字符,修饰符组成的文字模式

普通字符

代表本身的含义

/axihe/ 此正则匹配的就是"axihe"

除了元字符以外的所有字符都属于普通字符,这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。

常用的元字符

很多教程都是甩一张元字符的表格,让学生去背,我觉得这事不对的,我来带你们学习下如何记这些元字符。

现在不理解没有关系,后面会慢慢的讲

限定符

限定符,也有成为量词元字符,用来设置出现的次数

元字符 描述
* 匹配前面子表达式 零次到多次
+ 匹配前面子表达式 一次到多次
? 匹配前面子表达式 零次或一次(还是指明一个非贪婪限定符,后面会介绍)
{n} 出现 n 词
{n,} 出现 n 次到多次
{n,m} 出现 n 次到 m 次

星号*

axih*e,可以匹配 axie、axihe、axihhhhhhhhhe 等,* 号代表字符可以不出现,也可以出现一次或者多次(0 次、或 1 次、或多次)。

加号*

axih+e,可以匹配 axihhe、axihhhhe、axihhhhhhhhhe 等,+ 号代表前面的字符必须至少出现一次(1 次或多次)。

问号?

colou?r 可以匹配 color 或者 colour,? 问号代表前面的字符最多只可以出现一次(0 次、或 1 次)。

定位元字符

字符 描述
^ 以哪一个元字符作为开始
$ 以哪一个元字符作为结束
\b 匹配一个单词边界
\B 非单词边界匹配

注意:不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。

^

若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。

^once

^,只匹配以 once 开头的字符串。例如"once aaa"匹配,与"aaa once"不匹配。

$

正如如 ^ 符号表示开头一样,若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。

once$

这个模式与"aaa once"匹配,与"once aaa"不匹配。

^ 和 $ 同时使用

字符 ^ 和 $ 同时使用时,表示精确匹配(字符串与模式一样)。例如:

^once$

只匹配once,与"once aaa”/“aaa once"都不匹配

^a$ 字母 a

没有 ^ 和 $

如果一个模式不包括 ^ 和 $,那么它与任何包含该模式的字符串匹配。

once

与"once aaa”/“aaa once”/“aaa once bbb"都是匹配的

非打印元字符

就是匹配肉眼不可见的字符

字符 描述
\n 匹配一个换行符。
\r 匹配一个回车符。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。
\S 匹配任何非空白字符。
\t 匹配一个制表符(一个 tab 键,四个空格)。

所以如果我们要检测一个字符串是否以制表符开头,可以用^\t

类似的,用\n 表示”新行”,\r 表示回车。

其他的特殊符号,可以用在前面加上反斜杠,

  • 如反斜杠本身用 \\ 表示,
  • 点用 \. 表示,以此类推。

特殊元字符

单个或者组合在一起代表特殊的含义

所谓特殊字符,就是一些有特殊含义的字符,如上面说的 axih*e 中的 *,简单的说就是表示任何字符串的意思。

如果要查找字符串中的 * 符号,则需要对 \* 进行转义,即在其前加一个 /axih\*e/ 匹配 axih*e

元字符 描述
\ 转移字符(普通 ->特殊 ->普通)
\d 0 至 9 之间的一个数字
\D 非 0 至 9 之间的一个数字(可以这样记:大写和小写的意思相反)
. 除了\n(换行符)以外的的任意字符
\w 数字,字母,下划线的任意字符,等价于[A-Za-z0-9_]
\W 上一个取反,等价于 [^A-Za-z0-9_]
x y
[xyz] x 或者 y 或者 z 中的一个字符
[^xyz] 除了 x / y / z 以外的字符
[a-z] 指定 a-z 这个范围内的任意字符,比如上面的用户名验证例子。
[0-9a-zA-Z_]这就相当于\w
[^a-z] 上一个取反,不在 a-z 这个范围内的
() 正则中的分组符号,标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。
(?:) 只匹配不捕获
(?=) 正向预查
(?!) 反向预查

\d 包含数字

let reg = /\d+/;
console.log(reg.test('axihe.com创建于2018年'));//true
console.log(reg.test('2018axihe.com'));//true
console.log(reg.test('axihe.com2018'));//true

^ 以哪一个元字符作为开始

let reg = /^\d/;
console.log(reg.test('axihe.com创建于2018年'));//false
console.log(reg.test('2018axihe.com'));//true
console.log(reg.test('axihe.com2018'));//false

$ 以哪一个元字符作为结束

let reg = /\d$/;
console.log(reg.test('axihe.com创建于2018年'));//false
console.log(reg.test('2018axihe.com'));//false
console.log(reg.test('axihe.com2018'));//true

上面三个匹配方式,可以对比的记忆

验证手机号码

做一个例子,验证手机号码

let reg = /^1\d{10}$/;
console.log(reg.test(17899999999));//true

**.**除了\n(换行符)以外的的任意字符

. 不是小数点,换行符以外的的任意字符

let reg = /^2.3$/;
console.log(reg.test("2.3"));//true
console.log(reg.test("2@3"));//true
console.log(reg.test("23"));//false

转义字符: 把特殊符号转为普通的

\.代表小数点

let reg = /^2\.3$/;
console.log(reg.test("2.3"));//true
console.log(reg.test("2@3"));//false
console.log(reg.test("23"));//false

下面三个一定要理解!!!

let reg = /^\d$/;
console.log(reg.test("\d"));//false
console.log(reg.test("d"));//false
console.log(reg.test("1"));//true
let reg = /^d$/;
console.log(reg.test("\d"));//true
console.log(reg.test("d"));//true
console.log(reg.test("1"));//false
let reg = /^\\d$/;
console.log(reg.test("\\d"));//true
console.log(reg.test("d"));//false
console.log(reg.test("1"));//false

字符串中间的转义

"阿西河\n前端教程"
"阿西河\\n前端教程"

x|y

下面是一个比较经典的例子,匹配 18 或者 29;

let reg = /^18|29$/;
console.log(reg.test("18"));//true 18开头
console.log(reg.test("29"));//true 29结尾
console.log(reg.test("129"));//true 1开头,29结尾
console.log(reg.test("189"));//true 18开头,9结尾
console.log(reg.test("1829"));//true 18开头,29结尾
console.log(reg.test("829"));//true 29结尾
console.log(reg.test("182"));//true 18开头

其实我就是想要 18 或者 29,上面都是 true;这是 x|y 的误区,直接使用*x|y会存在一个相对比较乱的问题;

在数学里也会有类似的情况,比如想计算 1+2,然后乘 3+1,结果应该是 12;但是直接写 1+2*3+1得到的就是8, 而不是 12;

这时候我们会用 () 改变计算的优先级;(1+2)*(3+1), 这也就可以得到我们想要的 12 啦;代码里也是类似

**()**分组

let reg = /^(18|29)$/;
console.log(reg.test("18"));//true
console.log(reg.test("29"));//true
console.log(reg.test("129"));//false
console.log(reg.test("189"));//false
console.log(reg.test("1829"));//false
console.log(reg.test("829"));//false
console.log(reg.test("182"));//false

注意使用的是/^(18|29)$/;, 而不是/^(18)|(29)$/;

[]

正则表达式通常用来验证用户的输入,当用户提交一个 FORM 以后,要判断输入的手机号码、地址、EMAIL 等是否有效,用普通的基于字面的字符是不够的,要用一种更自由的描述我们要的办法,它就是字符簇,也叫集合,就把所有字符放在一个方括号里,用连字号可以表示一个字符的范围

[a-z] //匹配所有的小写字母
[A-Z] //匹配所有的大写字母
[a-zA-Z] //匹配所有的字母
[0-9] //匹配所有的数字
[0-9\.\-] //匹配所有的数字,句号和减号

[]: 分为二个重点

第一:中括号内出现的字符大部分情况下代表本身的含义

注意输大部分情况下

let reg = /^[@+]$/;
console.log(reg.test("@"));//true
console.log(reg.test("+"));//true
console.log(reg.test("@@"));//false
console.log(reg.test("@+"));//false
let reg = /^[@+]+$/;
console.log(reg.test("@@"));//true
console.log(reg.test("@+"));//true

但是:\d比较特殊,\d在中括号内还是 0-9 的意思

let reg = /^[\d]$/;
console.log(reg.test("d"));//false
console.log(reg.test("\\"));//false
console.log(reg.test("8"));//true

如果想要使用\d本身,需要用到上面说的转义

let reg = /^[\\d]$/;
console.log(reg.test("d"));//true
console.log(reg.test("\\"));//true
console.log(reg.test("8"));//false

第二:中括号内不存在多位数

let reg = /^[18]$/;
console.log(reg.test("1"));//true
console.log(reg.test("8"));//true
console.log(reg.test("18"));//false

比如/^[10-29]$/;意义是 1 或者 0-2 或者 9;

let reg = /^[10-29]$/;
console.log(reg.test("1"));//true
console.log(reg.test("9"));//true
console.log(reg.test("0"));//true
console.log(reg.test("2"));//true
console.log(reg.test("10"));//false
let reg = /^[\(10-29\)]$/;
console.log(reg.test("1"));//true
console.log(reg.test("9"));//true
console.log(reg.test("0"));//true
console.log(reg.test("2"));//true
console.log(reg.test("10"));//false
console.log(reg.test("("));//true
console.log(reg.test(")"));//true

若要在中括号表达式中包括连字符-,请采用下列方法之一:

用反斜杠将它转义:

[\-]

将连字符放在中括号列表的开始或结尾。下面的表达式匹配所有小写字母和连字符:

[-a-z]
[a-z-]
匹配由 1 个小写字母和 1 位数字组成的字符串

要匹配一个由一个小写字母和一位数字组成的字符串,比如”z2”、”t6”或”g7”,但不是”ab2”、”r2d3” 或”b52”的:

^[a-z][0-9]$

尽管、[a-z] 代表 26 个字母的范围,但在这里它只能与第一个字符是小写字母的字符串匹配。

所以还需要[0-9]

匹配由 1 个非数字的字符和 1 位数字组成的字符串

前面曾经提到 ^ 表示字符串的开头,但它还有另外一个含义。

当在一组方括号里使用 ^ 时,它表示"非"或"排除"的意思,常常用来剔除某个字符。

^[^0-9][0-9]$

这个模式与”&5”、”g7”及”-2”是匹配的,但与”12”、”66”是不匹配的。

[^a-z] //除了小写字母以外的所有字符
[^\\\/\^] //除了(\)(/)(^)之外的所有字符
[^\"\'] //除了双引号(")和单引号(')之外的所有字符
所有包含一个以上的字母、数字或下划线的字符串
^[a-zA-Z0-9_]{1,}$
^[a-zA-Z0-9_]+$
扩展到更多的单词或数字

匹配所有的正整数

^[1-9][0-9]{0,}$
^[1-9][0-9]*$

匹配所有的整数

^\-{0,1}[0-9]{1,}$
^\-?[0-9]+$

匹配所有的浮点数

^\-?[0-9]{1,}\.?[0-9]{1,}$
^[-]?[0-9]+\.?[0-9]+$
^[-]?[0-9]+(\.[0-9]+)?$
  • 以一个可选的负号 [-]? 开头 ^
  • 跟着 1 个或更多的数字 [0-9]+
  • 一个小数点 .
  • 再跟 1 个或多个数字 [0-9]+
  • 并且后面没有其他任何东西$

常用的修饰符

修饰符有三个,分别i/m/g,为了方便记忆,记成img(图片的标签)

可以在上帝视角那里查看修饰符的方法,

* i => ignoreCase   忽略单词大小写匹配
* m => multiline    可以进行多次匹配
* g => global       全局匹配

忽略单词大小写匹配

/AXI/.test('axihe.com')

上面因为没有大写的 AXI,所以返回 false

再看加i以后的

/AXI/i.test('axihe.com')

true, 同样没有大写的 AXI,但是忽略了大小写,所以返回 true。

单独说括号

匹配重复单词

提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例:

Is is the cost of of gasoline going up up?

上面的句子很显然有多个重复的单词。如果能设计一种方法定位该句子,而不必查找每个单词的重复出现,那该有多好。下面的正则表达式使用单个子表达式来实现这一点:

查找重复的单词:

let str = "Is is the cost of of gasoline going up up";
let patt1 = /\b([a-z]+) \1\b/ig;
console.log(str.match(patt1));// ["Is is", "of of", "up up"]

捕获的表达式,正如 [a-z]+ 指定的,包括一个或多个字母。

正则表达式的第二部分是对以前捕获的子匹配项的引用,即,单词的第二个匹配项正好由括号表达式匹配。\1 指定第一个子匹配项。

单词边界元字符确保只检测整个单词。否则,诸如 “is issued” 或 “this is” 之类的词组将不能正确地被此表达式识别。

正则表达式后面的全局标记 g 指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。

表达式的结尾处的不区分大小写 i 标记指定不区分大小写。

尝试不看本表,能不能记起上面的一些功能;

通用资源符分解为组件

假定您想将下面的 URI 分解为协议(ftp、http 等等)、域地址和页 / 路径:

http://www.axihe.com:80/edu/html/edu/home.html

下面的正则表达式提供该功能:

输出所有匹配的数据:

let str = "http://www.axihe.com:80/edu/html/edu/home.html";
let patt1 = /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/;
let arr = str.match(patt1);
for (let i = 0; i < arr.length ; i++) {
    console.log(arr[i]);
}

运行的结果

http://www.axihe.com:80/edu/html/edu/home.html
http
www.axihe.com
:80
/edu/html/edu/home.html

第三行代码 str.match(patt1) 返回一个数组,实例中的数组包含 5 个元素,索引 0 对应的是整个字符串,索引 1 对应第一个匹配符(括号内),以此类推。

第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。

第二个括号子表达式捕获地址的域地址部分。子表达式匹配 : 和 / 之后的一个或多个字符。

第三个括号子表达式捕获端口号(如果指定了的话)。该子表达式匹配冒号后面的零个或多个数字。只能重复一次该子表达式。

最后,第四个括号子表达式捕获 Web 地址指定的路径和 / 或页信息。该子表达式能匹配不包括 # 或空格字符的任何字符序列。

将正则表达式应用到上面的 URI,各子匹配项包含下面的内容:

  • 第一个括号子表达式包含 http
  • 第二个括号子表达式包含 www.axihe.com
  • 第三个括号子表达式包含 :80
  • 第四个括号子表达式包含 /edu/html/edu/home.html

些正则表达式示例

正则表达式 描述
/\b([a-z]+) \1\b/gi 一个单词连续出现的位置。
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ 将一个URL解析为协议、域、端口及相对路径。
/^(?:Chapter|Section) [1-9](0-9){0,1}$/ 定位章节的位置。
/[-a-z]/ a至z共26个字母再加一个-号。
/ter\b/ 可匹配chapter,而不能匹配terminal。
/\Bapt/ 可匹配chapter,而不能匹配aptitude。
/Windows(?=95 |98 |NT )/ 可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后,从Windows后面开始进行下一次的检索匹配。
/^\s*$/ 匹配空行。
/\d{2}-\d{5}/ 验证由两位数字、一个连字符再加 5 位数字组成的 ID 号。
/<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/ 匹配 HTML 标记。

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了