吃透js中正则表达式

栏目: JavaScript · 发布时间: 6年前

内容简介:我们在开发的过程中总会碰到一些需求需要做字符串匹配,当遇到一些稍微复杂一点的匹配规则时,如果我们对正则还不那么清晰,我们总是会去网上搜索一些现成的正则匹配,ctrl+c,ctrl+v。时间长了我们对这种修修补补的方式不厌其烦。那么今天就对正则表达式做足功夫,磨刀不误砍柴工,首先推荐一个学习正则的一个可视化的工具网址:regexper.com,输入正则规则即可生成匹配规则的流程图。了解并吃透正则会为我们以后开发节省很多时间和精力,一劳永逸。先从最基本的概念开始吧,let go!概念:有特殊含义的特殊字符,eg

我们在开发的过程中总会碰到一些需求需要做字符串匹配,当遇到一些稍微复杂一点的匹配规则时,如果我们对正则还不那么清晰,我们总是会去网上搜索一些现成的正则匹配,ctrl+c,ctrl+v。时间长了我们对这种修修补补的方式不厌其烦。那么今天就对正则表达式做足功夫,磨刀不误砍柴工,首先推荐一个学习正则的一个可视化的 工具 网址:regexper.com,输入正则规则即可生成匹配规则的流程图。了解并吃透正则会为我们以后开发节省很多时间和精力,一劳永逸。先从最基本的概念开始吧,let go!

元字符

概念:有特殊含义的特殊字符,eg: * + ? $ ^ . | \ ( ) { } [ ]等

通用含义元字符

在大部分语言语境中代表同一种含义,如下表:

字符 含义
\t 水平制表符
\v 垂直制表符
\n 换行符
\r 回车符
\0 空字符
\f 换页符
\cX Ctrl+X

其他含义元字符

1. 字符类

  • 我们可以使用元字符[]来构建一个简单的字符类
  • 所谓的类是指符合某些特性的对象,一个泛指,而不是特指某个字符
  • 表达式[abc]归为一类,表达式可以匹配这些类的字符

2. 字符类取反

  • 我们可以使用元字符^来创建反向类/负向类
  • 反向类的意思是不属于某个类的内容
  • 表达式[^abc]表示不是字符a或b或c的内容
    吃透js中正则表达式

3. 范围类

  • 正则表达式还提供了范围类
  • 我们使用[a-z]来连接两个字符表示从a到z的任意字符
  • 这是个闭区间也就包含a和z本身
    吃透js中正则表达式

4. 预定义类

  • 正则表达式提供了一些特殊字符表示自一组比较复杂的匹配规则,如下表:
字符 等价 含义
. [^\r\n] 除了回车符和换行符之外的所有字符
\d [0-9] 数字字符
\D [^0-9] 非数字字符
\s [\t\n\x0B\f\r] 空白符
\0 [^\t\n\x0B\f\r] 非空白符
\w [a-zA-Z_0-9] 单词字符(字母数字下划线)
\W [^a-zA-Z_0-9] 非单词字符

5. 边界

  • 正则表达式还提供了几个常用的边界匹配字符,如下表:
字符 含义
^ 以xxx开始
$ 以xxx结束
\b 单词边界
\B 非单词边界

6. 量词

字符 含义
? 出现一次或0次(最多出现一次)
+ 出现一次或多次(最少出现一次)
* 出现0次或多次(任意次)
{n} 出现n次
{n, m} 出现n到m次
{n, } 至少出现n次

js正则的贪婪模式和非贪婪模式

  1. 贪婪模式:\d{3,6}匹配数字3到6次,那么在匹配的过程中会尽可能多的的匹配。如:
'12345678'.replace(/\d{3,6}/, 'X')  // "X78"
复制代码
  1. 非贪婪模式:在量词后面加上 ? ,可以让正则表达式尽可能少的匹配,也就是非贪婪模式。
'12345678'.replace(/\d{3,6}?/, 'X')  // "X45678"
复制代码

分组

对一组正则规则加(),可以对正则进行分组,

比如:对taoyouyou这组单词匹配三次 taoyouyou{3}

吃透js中正则表达式

可视化后能看到只是最后一个单词u重复了3次,并没有达到目的 (taoyouyou){3}

吃透js中正则表达式

taoyouyou重复了3次

反向引用

例如实现2019-02-22 => 02/22/2019的转化。

吃透js中正则表达式
'2019-02-22'.replace(/(\d{4})-(\d{2})-(\d{2})/,'$2/$3/$1')   //  "02/22/2019"
复制代码

忽略分组

不需要捕获某些分组只需要在分组内加 ?: 就可以了。 (?:taoyouyou).(ok)

吃透js中正则表达式

前瞻

  • 正则表达式从文本头部向尾部解析,文本尾部方向称为 “前”
  • 前瞻:正则表达式匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反
  • JavaScript不支持后顾
  • 符合和不符合某项断言称为肯定/正向匹配和否定/负向匹配
名称 正则 含义
正向前瞻 exp(?=assert)
负向前瞻 exp(?!assert)
正向后顾 exp(?<=assert) JavaScript不支持
负向后顾 exp(?<!assert) JavaScript不支持

正则对象属性

  • global: 是否全文匹配,默认false,匹配规则后面加g开启
  • ignoreCase: 是否大小写敏感, 默认false,匹配规则后面加i开启
  • multiline: 多行搜索, 默认false,匹配规则后面加m开启
  • lastIndex: 当前表达式匹配内容最后一个字符的下一个位置
  • source: 正则表达式的文本字符串 这几个属性都是只读属性
reg=/\d/gmi
reg.global  // true
reg.ignoreCase  // true
reg.multiline  // true
reg.lastIndex  // 0
reg.source  // "\d"
复制代码

对象方法

1. 正则test方法

RegExp.prototype.test(str)

  • 用于测试字符串参数中是否存在匹配正则表达式模式的字符串
  • 如果存在则返回true,否则返回false

var reg2=/\w/g; 进行reg2.test('ab')时,第三次会变成false 原因:while(reg2.test('ab')){ console.log(reg2.lastIndex); } 即进行test时,正则表达式的lastIndex会发生变化 输出:1 2 表示第一个匹配上了、第二个匹配上了

2. 正则exec方法

RegExp.prototype.exec(str)

  • 使用正则表达式模式对字符串参数进行匹配搜索,并将更新全局对象属性以反映匹配结果
  • 如果没有匹配则返回null,否则返回一个结果数组: 属性index(声明匹配文本的第一个字符的位置), input(存放被检索的字符串string) 数组本身: [与正则表达式相匹配的文本,与正则对象的第一个子表达式(分组)相匹配的文本, 与正则对象的第二个子表达式(分组)相匹配的文本,…… ]
var reg3=/\d(\w)(\w)\d/;    // 非全局搜索只能匹配到第一个结果
var reg4=/\d(\w)(\w)\d/g;   // 全局搜索匹配全文
var ts = '$1az2bb3cy4dd5ee'
var ret1= reg3.exec(ts)     // (3) ["1az2", "a", "z", index: 1, input: "$1az2bb3cy4dd5ee", groups: undefined]
console.log(reg3.lastIndex+'\t'+ret1.index+'\t'+ret1.toString())
// "0 1 1az2, a, z"
while(ret2 = reg4.exec(ts)){
  console.log(reg4.lastIndex+'\t'+ret2.index+'\t'+ret2.toString())
}
// "5 1 1az2, a, z"
// "11 7 1az2, a, z"
复制代码

3. 字符串对象search方法

String.prototype.search(reg)

  • search方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串
  • 返回第一个匹配结果index,查不到返回-1
  • search()不执行全局匹配,它将忽略标志g, 并总是从字符串的开始进行检索

4. 字符串对象match方法

String.prototype.match(reg)

  • match方法将检索字符串,以找到一个或多个与regexp相匹配的字符串
  • regexp是否具有标志g对结果影响很大

非全局调用

  • 返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本
  • 除了常规的数组元素之外,返回的数组还含有2个对象属性:index声明匹配文本的起始字符在字符串的位置,input声明对stringObject的引用
  • 全局调用的返回与正则表达式的exec方法相类似,即:[与正则表达式相匹配的文本,与正则对象的第一个子表达式(分组)相匹配的文本, 与正则对象的第二个子表达式(分组)相匹配的文本,…… ],数组有index和input属性

全局调用

  • 如果regexp具有标志g则match方法将执行全局检索,找到字符串中的所有匹配子字符串
  • 没有找到任何匹配的子串,则返回null
  • 如果找到了一个或多个匹配子串,则返回-一个数组
  • 数组元素中存放的是字符串中所有的匹配子串,而且也没有index属性或input属性
var reg3=/\d(\w)(\w)\d/;    // 非全局搜索只能匹配到第一个结果
var reg4=/\d(\w)(\w)\d/g;   // 全局搜索匹配全文
var ts = '$1az2bb3cy4dd5ee'
var ret1= ts.match(reg3)   // (3) ["1az2", "a", "z", index: 1, input: "$1az2bb3cy4dd5ee", groups: undefined]   
console.log(reg3.lastIndex+'\t'+ret1.index)  // 0, 1
var ret2 = ts.match(reg4)  // (2) ["1az2", "3cy4"]
console.log(reg4.lastIndex+'\t'+ret2.index)   // 0 undefined
复制代码

5. 字符串对象split方法

String.prototype.split(reg)

  • 我们经常使用split方法把字符串分割为字符数组 eg: 'a,b,c,d'.split(','); //["a", "b", "c", "d"]
  • 在一些复杂的分割情况下我们可以使用正则表达式解决 eg: 'alb2c3d'.split(/\d/; //["a", "b", "c", "d"]

6. 字符串对象replace方法

String.prototype.replace

  • String.prototype.replace(str, replaceStr)
  • String.prototype.replace(reg, replaceStr)
  • String.prototype.replace(reg, function) function参数含义 function会在每次匹配替换的时候调用,有四个参数 1、匹配字符串 2、正则表达式分组内容,没有分组则没有该参数 3、匹配项在字符串中的index 4、原字符串
'a1b2c3d4e5'.replace(/\d/g, function(match, index, origin){
  return parseInt(match) + 1;
})  // "a2b3c4d5e6"

'a1b2c3d4e5'.replace(/(\d)(\w)(\d)/g, function(match, group1, group2, group3, index, origin){
  console.log(match)
  return group1 + group3;
})  
// 1b2
// 3d4
// "a12c34e5"

复制代码

原文地址:taoyouyou.gitee.io


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP and MySQL Web Development

PHP and MySQL Web Development

Luke Welling、Laura Thomson / Sams / July 25, 2007 / $49.99

Book Description PHP and MySQL Web Development teaches you to develop dynamic, secure, commerical Web sites. Using the same accessible, popular teaching style of the three previous editions, this b......一起来看看 《PHP and MySQL Web Development》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器