正则表达式基础教程【javascript】

实例化

javascript中RegExp有两种实例化方式:字面量构造函数

  • 字面量:var reg = /[a-z0-9]*/g
  • 构造函数:var reg = new RegExp('/[a-z0-9]/', 'g' )

参数

可选参数有三个:g(global 全局匹配)、i(ignore case 忽略大小写)、m(multiple lines 多行匹配),先写一个简单的正则表达式来看看具体效果。

  • 参数g
    不加g参数:
    不加g参数
    字符串中有两个is单词,不加g参数只能匹配到第一个。
    现在加上g参数:
    加g参数
    加上g参数后匹配并替换了所有的is单词,表达式中\b表示单词边界,即仅仅匹配独立的is单词,即使字符串中包含is也不行,看看不加\b的效果:
    不加\b效果
    包含is的单词都被替换了。

  • 参数i
    不加参数i表示严格区分大小写,效果如下:
    不加参数i
    可以匹配is,但是无法匹配Is
    加上参数i的效果如下:
    加上参数i效果
    加上参数i后,isIs都可以匹配到。

  • 参数m
    具体含义是:将开始和结束字符(^$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由\n\r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。后面详细讲解。

字符

正则表达式字符分为两类:原义文本字符和元字符

  • 原义文本字符是字符串匹配本身,比如/\bis\b/g中的is,就是为了匹配is
  • 元字符是有特殊意义的非字母字符,在不同的场景下有不同的含义,包括 . * + ? ^ $ · | \ () [] {}

范围 []

[]表示一个字符集合,凡是符合规则的字符都会被匹配到。
[]演示
/[abcd]/g/[a-d]/g都表示全局匹配a、b、c、d中的任意一个字符(闭区间,两个边界都包含),[]甚至可以包含多个范围。
[]演示2
/[a-d1-8]/g表示全局匹配a-d或者1-8中的任意单个字符,在这个表达式中-有了特殊意义,如果只想匹配“-”这个字符,可以写成以下形式:
[]中-的匹配
[]还可以取反,在[]内加上^,即[^],意思是匹配该范围外的所有字符
[]取反
对比这两个结果就可以看出来。

正则表达式中预定了一些常用的范围

字符等价字符含义
.[^\r\n]除回车和换行外的任意字符
\d[0-9]数字字符
\D[^0-9]非数字字符
\s[\t\n\x0B\f\r]空白符
\S[^\t\n\x0B\f\r]非空白符
\w[a-zA-Z0-9_]单词字符(数字、字母、下划线)
\W[^a-zA-Z0-9_]非单词字符

边界 ^ $

^表示以xxx开始(在[]中表示取反),$表示以xxx结束,前文提到的\b表示单词边界,\B表示非单词边界
边界^
/A/g匹配到了两个A,/^A/g只能匹配开头的A。同理,看看$效果
边界$
后者只匹配到了结尾的A。
再来看看参数中的m多行匹配
多行匹配
多行匹配
str是一个多行字符串(含有\r\n),用表达式/^This/g全局匹配却只能匹配到第一个"This",肉眼看到三行,对编译器来说只有一行,此时如果想要匹配三行,就可以加参数m进行多行匹配。
多行匹配

数量词 * + ? {}

  • {m,n}匹配m到n次(闭区间),{m}匹配m次,{m,}至少匹配m次
  • *匹配任意次,等价于{0, }
  • ?匹配0次或者1次,至多1次,等价于{0,1}
  • +匹配1次或者多次,至少1次,等价于{1,}
    除此之外,?还可以指定贪婪模式非贪婪模式,这里贪婪的意思和运算符的贪婪是一个意思,就是尽可能多的匹配,举个例子
    贪婪模式
    表达式/\d{3,7}/g理论上可以匹配3-7个数字,默认是贪婪的,所以匹配7个,如果想指定非贪婪模式看下图
    非贪婪模式
    表达式/\d{3,6}?/g中的?指定非贪婪模式,尽可能少的匹配,所以"123"替换成了"X",“456”也替换成了"X"。

分组 ()

有时想连续匹配某一段字符而不是某一个字符,可能会这样写
分组
本来想把"hellohellohellooo"替换成"Xoo",没想到替换成了"hellohelloX",也就是说/hello{3}/g是匹配了3个"o",而不是3个"hello",这时便可以使用分组
分组2
|表示“或”,直接看例子
|或
/hello|world/g表示既可以匹配"hello"也可以匹配"world",如果把|()结合起来会有什么效果
|或
/hel(lo|wo)rld/g表示既可以匹配"helworld"也可以匹配"hellorld",也就是"lo"和"wo"任取一个。
利用()实现反向引用,如何把"2018-11-22"替换成"22/11/2018"?前面所有的替换都是把匹配到的字符串替换成固定的内容,在这里却不是。
反向引用
/(\d{4})-(\d{1,2})-(\d{1,2})/g把匹配到的字符串分为三组分别是(\d{4})(\d{1,2})(\d{1,2}),分组内容可以用$1$2$3取到。

前瞻和后顾

注意:正则表达式从文本头部向尾部解析,所以文本尾部方向叫**前**
前瞻意思是匹配到内容后,还要向前检查是否符合断言,后顾同理。比如在写爬虫,解析页面时,想提取<body>hello world</body>标签中的字符串"hello world",但是不想要标签<body></body>,这时便可以用到前瞻和后顾。
'<body>helloworld</body>helloworld'.replace(/(?<=<body>)[a-z]*(?=<\/body>)/g, 'X')
前瞻和后顾
上图可以看到,只有<body></body>之间的字符串被替换了,标签本身和标签外的字符都没有被替换。说明/(?<=<body>)[a-z]*(?=<\/body>)/g表达式不仅要匹配符合[a-z]*,还要符合前后的断言。如果需要写非命题的断言,参考下面的例子。
'<body>helloworld</body>helloworld'.replace(/(?<!<body>)[a-z]{9,}(?!<\/body>)/g, 'X')
前瞻后顾非命题

表达式逻辑非
前瞻(?=assert)(?!assert)
后顾(?<=assert)(?<!assert)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值