资讯专栏INFORMATION COLUMN

最简单的js正则表达式相关事123

renweihub / 1021人阅读

摘要:可以使用元字符来构建一个简单的类,所谓类是指符合某些特征的对象,一个泛指,而不是特指某个字符,例如表达式把字符或或归为一类,表达式可以匹配这类的字符,即匹配中的,但是是取反的意思。

正则表达式不管是前后端开发,都是很容易碰到的痛点,就像前女友一样时不时的让你这么痛一下,最近抽空重新学习了下js里面的正则表达式,随记之。

正常水平本文阅读需要10分钟即可,10分钟回顾知识点巩固一下基础。

一:理论部分

1. 实例化两种方式

 var reg = /is/g;  // 自变量
 var reg = new RegExp("is","g");  // 对象实例化方式,好处是可以传递变量进来

2. 修饰符 或者叫做 对象只读属性

global:是否全文搜索,默认false  reg.global

ignoreCase:是否大小写敏感,默认是false  reg.ignoreCase

multiline:多行搜索,默认值是false

lastIndex:当前表达式匹配内容的最后一个字符的下一个位置

source:正则表达式的文本字符串

这些属性我们可以在正则对象的实例化对象身上看的到,也是我们正则表达式的修饰符号。

3. 常见的表达式模式

[abc]    查找方括号之间的任何字符。
[0-9]    查找任何从 0 至 9 的数字。
(x|y)    查找任何以 | 分隔的选项。

4. 元字符

(1)**原义文本字符**:代表它原来含义的字符 例如:abc、123
(2)**元字符**:在正则表达式中有特殊意义的非字母字符 例如:表示匹配单词边界,
(3) 在正则表达式中具体特殊含义的字符:* + ? $ ^ .  () {} []

5. 字符类

一般情况下正则表达式一个字符对应字符串一个字符, 表达式 ab 的含义是: 一个字母a一个字母b加一个水平制表符 回车 换行。

可以使用元字符[]来构建一个简单的【类】,所谓类是指符合某些特征的对象,一个泛指,而不是特指某个字符,例如表达式[abc]:把字符 a 或 b 或 c 归为一类,表达式可以匹配这类的字符,即匹配abc中的,但是 [^abc] 是取反的意思。

6. 范围类

正则表达式提供了范围类,可以使用[a-z]来连接两个字符类表示从a到z的任意字符,这是一个闭区间,也就是包含a和z;
可以进行连写:[a-zA-Z],但是如果同时范围内包含字符"-":如[0-9-] :"2012-08-08".replace(/[0-9-]/,"");

7: 预定义类 匹配常见的字符类

.  等价于 [^
] 表示除了回车符和换行符之外的所有的字符

d 等价于 [0-9] 数字字符 d:digit

D [^0-9] 非数字字符

s 等价于 [	
x0Bf
] 空白符 s:space

S 非空白符号

w 等价于 [a-zA-Z_0-9] 单词字符(字母、数字下划线) w:word


边界匹配
  ^ 以XXX开始
  $ 以XXX结束
   单词边界
  B 非单词边界

8 量词: 作用于紧挨着的字母,并不是整个单词,需要分组才能拿到整个单词

? 出现0或1次(最多1次)

+  出现1或多次(至少1次)

*  出现0或多次(任意次)

{n}  出现n次

{n,m}  出现n到m次

{n,}  至少出现n次

量词放在元字符后面,如d+

9:两种模式

**贪婪模式**:尽可能多地匹配,直到匹配失败 即匹配过程中有多个条件符合的话,会选择最多的那一种

**非贪婪模式**:让正则表达式尽可能少的匹配,一旦成功匹配则不再继续尝试,**在【量词】后面加上【?】即可**


 eg: "12345678".replace(/d{3,6}/g,"X")  "X78"贪婪模式:尽可能多的匹配

    "12345678".replace(/d{3,6}?/g,"X") "XX78"非贪婪模式:尽可能少的匹配

10 分组

(1) 使用()可以达到分组的功能,使量词作用于分组 (Byron){3},如果直接Byron{3}则匹配到的三Byronnn。 默认是贪婪的捕获性质的分组。

 例子:小写字母连续出现3次
"a1b2c3d4".replace(/[a-z]d{3}/g,"Q");  //"a1b2c3d4"
"a1b2c3d4".replace(/([a-z]d){3}/g,"Q"); //"Qd4"


// 通过$1 _ 取到捕获到的值。
var str = "hello world";            
var pattern = /([a-z]+)s([a-z]+)/; 
console.log(RegExp.$1) //"hello" 第一个分组([a-z]+)的值


// 捕获性的分组
var str1 = "000aaa111";             
var pattern = /([a-z]+)(d+)/; //捕获性分组匹配
var arr = pattern.exec(str1);  
console.log(arr) // ["aaa111","aaa","111"]   结果子串也获取到了,这并不是我们想要的结果

(2). 使用 将正则表达式分成前后两部分 【或 |】

 "ByrCasperByronsper".replace(/Byr(on|Ca)sper/g,"Q"); // "QQ"

(3).反向引用 反向引用,捕获必须是在分组的基础之上进行操作的,后续案例中还要补充这个点。

例如 2015-12-25 => 12/25/2015 在分组的基础上,分组取值使用"$1 $2...."代表捕获分组内容。

(4). 非捕获性的分组,不希望捕获某些分组,只需要在分组内加上 ?:即可

例如"2015-07-09".replace(/(?:d{4})-(d{2})-(d{2})/g,"$2/$3/$1"); // "09/$3/07"

//非捕获性分组
var str2 = "000aaa111";
var pattern2 = /(?:[a-z]+)(?:d+)/; //非捕获性分组匹配
var arr2 = pattern2.exec(str2);  
console.log(arr2) //["aaa111"]  结果正确  

11 前瞻

js 不支持后顾 eg: 匹配到张三,而且还要看看他爹是不是叫李四

正则表达式从文本头部向尾部开始解析,文本尾部方向为“前”,头部方向为“后”

前瞻:正则表达式匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反(javascript不支持)

 符合断言:肯定/正向匹配      正向前瞻:exp(?=assert)
 不符合断言:否定/负向匹配    负向前瞻:exp(?!assert)

很重要的一点是, 前瞻中断言只作为判断条件,不参与规则部分的操作

12 正则相关的一些方法

  test 不支持全局匹配
   RegExp.prototype = {

        test: 不支持全局匹配  re.test(str)  重点在于检测 返回true/false
        : 返回数组【匹配项目,有子正则的话输出子匹配项目,具体哪一个开始匹配index】
   }

   String.prototype = {
        search: 找不到返回-1  str.seach(re);
        match: 返回匹配到的数组  str.match(re)  如果没有g只会匹配一次
        replace:
        split
   }
二:实战案例
**(1) is替换**

const s = "this is a book".replace(/is/,"~");  // "this ~ a book"
const s1 = "this is a book".replace(/Bis/,"~");  // "th~ is a book"
**(2) 把http 并且结尾是jpg的url 删除协议头,即返回//...jpg** 

https://cdn.baidu.com/images/asdas.jpg

http://cdn.hexun.com/images/asdas.jpg

https://cdn.baidu.com/images/asdas.png

http://cdn.sohu.com/images/asdas.jpg

https://cdn.baidu.com/images/asdas.jpg

http://cdn.baidu.com/images/asdas.png

https://cdn.baidu.com/images/asdas.png

正则:`/^http:(//.+.jpg)$/gi`
(3) 把下面是日期的全部替换为: 月-日-年 

02-03-2006

test/07/sd

05-10-2015

16555/12/45

1253645/2131/34

05-15-1998


正则:str.replace( /^(d{4})[/-](d{2})[/-](d{2})$/ $2-$3-$1)
(4)

// 正向前瞻 
const s4 = "v3asd7*5sd".replace(/w(?=d)/g,"~");  // "~3as~7*5sd"

// 负向前瞻  注意匹配项  是分组的结果 注意为什么没有使用全局匹配?
const s5 = "v3asd7*5sd".replace(/w(?!d)/,"~");  // "v~asd7*5sd"
(5)

// 非捕获性的分组是不会作为匹配项返回的
const str_0 = "window 98 is ok 11";
const re_0 = /window (?=d)/g; // 干脆不会作为结果出现
const re_1 = /window (?:d+)/g; // 非捕获性分组定义子表达式可以作为整体被修饰但是子表达式匹配结果不会被存储。
const re_2 = /window (d+)/g;  // 会作为匹配项目出现在子

console.log( re_0.exec(str_0) );
console.log( re_1.exec(str_0) );
console.log( re_2.exec(str_0) );


结果是:
[ "window ", index: 0, input: "window 98 is ok 11" ]
[ "window 98", index: 0, input: "window 98 is ok 11" ]
[ "window 98", "98", index: 0, input: "window 98 is ok 11" ]
(6)
var str_img = "img1.jpg,img2.jpg,img3.bmp";
var str_re_1 = /(?:w+)(?=.jpg)/g;
var str_re_2 = /(?:w+)(?:.jpg)/g;


console.log( str_img.match(str_re_1) )  //[ "img1", "img2" ]
console.log( str_img.match(str_re_2) )  // [ "img1.jpg", "img2.jpg" ]

// 上面使用的是match但是看下面代码执行的结果
console.log( str_re_1.exec(str_img) );  输出结果[ "img1", index: 0, input: "img1.jpg,img2.jpg,img3.bmp" ] 为什么不是全部的呢?

再看一下代码
var result;
while ( (result= str_re_1.exec(str_img)) !=null ){
   console.log(str_re_1.lastIndex)
   console.log(result)
}

>> 执行的结果是:

4
[ "img1", index: 0, input: "img1.jpg,img2.jpg,img3.bmp" ]
13
[ "img2", index: 9, input: "img1.jpg,img2.jpg,img3.bmp" ]


总结出,exec 不是全局的匹配结果
(7)手机号码中间4位 ****
console.log(
  "15201095029".replace(/(?:d{4})(?=d{4}$)/g,function($,$1){
      return "****"
  })
);
(8)转换为驼峰的写法
console.log(

  "app-com-up".replace(/-(w)/g,function($,$1){
     return $1.toUpperCase()
  })
);

(9)贪婪匹配
  .+是非贪婪匹配   
  .+?是贪婪匹配

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106771.html

相关文章

  • js正则达式入门

    摘要:说白了正则表达式就是处理字符串的我们可以用它来处理一些复杂的字符串。这个简单理解就是说字符出现的位置的右边必须匹配到这个表达式。这个就是说字符出现的位置的前边是这个表达式。 什么是正则表达式呢? 正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子串、将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等。 说白了正...

    A Loity 评论0 收藏0
  • 正则达式-温故而知新

    摘要:正则表达式重新整理学习,为了加深印象,发现了之前遗漏的一个非常重要的知识点优先选择最左端的匹配结果,这个规则上创建正则的方式直接字面量的创建通过双斜杠,在中间添加匹配的规则,这样就是一个正则表达式了通过构造函数创建通过构造函数来创建正则对象 正则表达式 重新整理学习,为了加深印象,发现了之前遗漏的一个非常重要的知识点优先选择最左端的匹配结果,这个规则 js上创建正则的方式 直接字面...

    snowell 评论0 收藏0
  • 正则从零到简单分析html标签

    摘要:对于正则之前一直是一个百度程序员也许超过一半甚至更多的程序员也是那么这次来学习一下正则表达式事出有因这部分介绍一下需求的由来与主要内容无关工作上有了这样的需求端从来的数据格式是也就是文章内容并夹杂着诸多标签和嵌套然而正在开发的是项目的标签 对于正则之前一直是一个百度程序员, 也许超过一半甚至更多的程序员也是, 那么这次来学习一下正则表达式. 事出有因 这部分介绍一下需求的由来, 与主要...

    antz 评论0 收藏0
  • js温故而知新5——学习廖雪峰js教程

    摘要:表示行的结束,表示必须以数字结束。用表示的就是要提取的分组。方法在匹配成功后,会返回一个,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。贪婪匹配需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。 对象 typeof 123; // number typeof NaN; // number typeof str; // string type...

    mayaohua 评论0 收藏0
  • [ JS 进阶 ] test, exec, match, replace

    摘要:用法介绍注为的实例为的实例用法说明返回值判断是否包含匹配结果包含返回,不包含返回。当为全局的对象的时候,替换每一项匹配项。如下表所示,它说明从模式匹配得到的字符串将用于替换。字符替换文本与中的第到第个子表达式相匹配的文本。 上面这四个方法在js中用的很多,但有时对它们又不清晰,所以有必要来总结一下。 对了,这篇文章可能会涉及到正则表达式相关知识,所以推荐没有正则基础的去看看这篇入门文章...

    why_rookie 评论0 收藏0

发表评论

0条评论

renweihub

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<